Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The real sense of list generators in haskell

Tags:

haskell

As I understand, the code

l = [(a,b)|a<-[1,2],b<-[3,4]]

is equivalent to

l = do
  a <- [1,2]
  b <- [3,4]
  return (a,b)

or

[1,2] >>= (\a -> [3,4] >>= (\b -> return (a,b)))

The type of such expression is [(t,t1)] where t and t1 are in Num.

If I write something like

getLine >>= (\a -> getLine >>= (\b -> return (a,b)))

the interpreter reads two lines and returns a tuple containing them.

But can I use getLine or something like that in list generators?

The expression

[x|x<-getLine]

returns an error "Couldn't match expected type [t0]' with actual typeIO String'"

But, of course, this works in do-notation or using (>>=).

What's the point of list generators, and what's the actual difference between them and do-notation?

Is there any type restriction when using list gens?

like image 693
edmi Avatar asked Dec 05 '22 19:12

edmi


2 Answers

That's a sensible observation, and you're not the first one to stumble upon that. You're right that the translation of [x|x<-getLine] would lead to a perfectly valid monadic expression. The point is that list comprehensions were, I think, first only introduced as convenience syntax for lists, and (probably) no one thought that people might use them for other monads.

However, since the restriction to [] is not really a necessary one, there is a GHC extension called -XMonadComprehensions which removes the restriction and allows you to write exactly what you wanted:

Prelude> :set -XMonadComprehensions 
Prelude> [x|x<-getLine]
sdf
"sdf"
like image 180
phipsgabler Avatar answered Dec 09 '22 13:12

phipsgabler


My understanding is that list comprehensions can only be used to construct lists.

However, there's a language extension called "monad comprehensions" that allows you to use any arbitrary monad.

https://ghc.haskell.org/trac/ghc/wiki/MonadComprehensions

like image 30
MathematicalOrchid Avatar answered Dec 09 '22 13:12

MathematicalOrchid