2016-02-11 41 views
4

真正意义据我所知,代码列表发电机在Haskell

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

相当于

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

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

的类型这样的表达的是[( t,t1)]其中t和t1在Num中。

如果我喜欢写东西

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

解释读取两行并返回一个包含它们的元组。

但我可以在列表生成器中使用getLine或类似的东西吗?

表达

[x|x<-getLine] 

返回错误 “不能匹配预期类型[t0]' with actual type IO字符串”“

但是,当然,这个作品在DO-符号或使用(>> =) 。

列表生成器有什么意义,它们和标记之间有什么实际区别?

使用列表生成时是否有任何类型限制?

回答

9

这是一个明智的观察,你不是在那蹒跚的第一个。你是对的,[x|x<-getLine]的翻译将导致一个完全有效的monadic表达式。关键是列表解析是我认为first仅作为列表的便利语法引入,并且(可能)没有人认为人们可以将它们用于其他单子。

然而,由于限制[]是不是真的一个必要条件,有一个GHC扩展名为-XMonadComprehensions这消除了限制,并允许你写你想要什么:

Prelude> :set -XMonadComprehensions 
Prelude> [x|x<-getLine] 
sdf 
"sdf" 
+1

我听到传言说内涵*用于*为任何monad工作,但错误信息是不可理解的,所以它被改变了。尽管如此,我还没有一个引用...... – MathematicalOrchid

+0

那么,如果在过去的日子里,翻译是纯粹的重写和独立于类型检查......也许在有人严格应用报告中的站点之前,这是有道理的。 – phg

+4

@MathematicalOrchid:有[此票](https://ghc.haskell.org/trac/ghc/ticket/4370)和[本维基页面](https://ghc.haskell。组织/ TRAC/GHC /维基/ MonadComprehensions);都表明MonadComprehensions最初被允许,然后被删除,并且随后通过语言扩展加回。 – Zeta