据我所知,代码
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 String'”
但是,当然,这可以使用do-notation或使用(&gt;&gt; =)。
列表生成器的重点是什么,它们与do-notation之间的实际区别是什么?
使用列表gens时是否有任何类型限制?
答案 0 :(得分:9)
这是一个明智的观察,你不是第一个偶然发现的人。你是对的,[x|x<-getLine]
的翻译会导致一个完全有效的monadic表达。关键是我认为列表推导只是作为列表的便捷语法引入的first,并且(可能)没有人认为人们可能会将它们用于其他monad。
但是,由于对[]
的限制并非真正必要,因此有一个名为-XMonadComprehensions
的GHC扩展名可以删除限制并允许您准确写出您想要的内容:
Prelude> :set -XMonadComprehensions
Prelude> [x|x<-getLine]
sdf
"sdf"
答案 1 :(得分:6)
我的理解是列表推导只能 用于构建列表。
然而,有一个名为“monad comprehensions”的语言扩展,允许你使用任意monad。