0
votes

I'm a new for Haskell. I've come across an error. The code is a little bit complex, but I realized it can be simplified as below.

import Data.Set (Set)
import qualified Data.Set as S

oA :: S.Set String
oA = S.empty

main::IO()
main = do
    let oA = S.fromList["a1","a2","a3","a4","a5"]
    print [ a | a <- oA ]
    return ()

This gives me an error as below.

Module.hs:10:22:
    Couldn't match expected type `[t0]' with actual type `Set [Char]'
    In the expression: oA
    In a stmt of a list comprehension: a <- oA
    In the first argument of `print', namely `[a | a <- oA]'

How can I solve the problem? From a sense of other programming languages (like java), [ Set [Char] a | a <- oA ] might work, but this is not accepted by Haskell compiler.

1
the problem is that at this point you don't need the Set yet: let oA = ["a1",...] and then [ a | a <- oA] will work - If I coud guess what you are trying to achieve I could try to help you further - Random Dev
see in your usual list-comprehension the oA needs to be a list as well, but you made it into a Set that is where the error happens - Random Dev
there is an extension to make this work with monads too but then Set is no monad (yet another slight problem) ... - Random Dev
@CarstenKönig Thanks. Honestly, I don't understand the difference between Set and List... Since I'm reproducing my mathematical model in Haskell, I've chosen not List but Set. In math, we use set, so... - Pengin
well ok - the Set and the sets from math you know are similar. You can think of a list as a ordered collection of things (in a set the order won't matter) - also you can have the same thing multiple times in a list (not in a set) - on top of that there are differences in their representation inside the programming language - in most cases you will want to deal only with lists as a beginner - it's the basic structure in FP (IMO) as it teaches you recursion and pattern-matching quite nicely - Random Dev

1 Answers

1
votes

As the comments point out, the problem is that things in a list comprehension have to be, well, lists. And you tried to use a set, which isn't a list.

(There's an extension that allows you to use the same syntax for any arbitrary monad, but that still doesn't help. Even though a set technically is a monad, due to technical difficulties you can't define Haskell's Set type as a monad. But that's another discussion.)

Addressing your comment "I don't understand the difference between Set and List"...

First, understand that computer programming languages are not like mathematics. They may use terms borrowed from mathematics, but they may use them to mean something wildly different from what you may be expecting. At all times, you must separate in your mind the mathematical definition of what (say) a set is, and the machine-oriented Set data-type that Haskell provides.

In this particular case, we have the list type [x], and the set type Set x.

  • Set x is a data structure that very roughly implements what you would expect from a mathematical set. It stores items, and you can check for set membership, and this is efficient at the machine level. In order to implement this, x is required to possess a total ordering. (Set is implemented as a search tree.)

  • [x] is more like a mathematical sequence of values. Unlike Set, there is no restriction on what type of data can be in a list. Also, there is no efficient membership queries. ([x] is a single-linked list.) What you can do is efficiently iterate over elements in sequence-order. Sets don't have an ordering, and Set isn't terribly fast for iterating over.

As you can see, for constructing a new collection of stuff from one or more existing collections of stuff, for a machine-efficient job, you want [x], not Set x.