gpt4 book ai didi

Haskell 列表理解和列表 Monad

转载 作者:行者123 更新时间:2023-12-03 22:56:39 25 4
gpt4 key购买 nike

我正在尝试编写一些自定义类型 Martix a ,这基本上是列表列表 [[a]] .当我尝试实现一个名为 colAt 的函数时,它应该给出矩阵的垂直元素,我首先使用列表理解:

colAt :: Int -> Matrix a -> [a]
colAt c m = [ e | r <- m, e <- r !! c ]
但是 Ghci 告诉我
Occurs check: cannot construct the infinite type: a ~ [a]
In the expression: r !! c
虽然 do 符号与
colAt :: Int -> Matrix a -> [a]
colAt c m = do
r <- m
return (r !! c)
是什么导致了这个错误?我认为基本上列表理解是列表符号的语法糖,但是鉴于此错误,我的理解是错误的?

最佳答案

您的理解是完全正确的:列表推导式确实只是 do 的语法糖符号!问题是您没有正确地对列表理解进行脱糖。
首先,让我们重复列表推导以供引用:

colAt :: Int -> Matrix a -> [a]
colAt c m = [ e | r <- m, e <- r !! c ]
现在,我将部分脱糖,以移动 r <- m有点超出理解范围:
colAt :: Int -> Matrix a -> [a]
colAt c m = do
r <- m
[e | e <- r !! c]
这很容易完全脱糖:
colAt :: Int -> Matrix a -> [a]
colAt c m = do
r <- m
e <- r !! c
e
与正确的实现进行比较:
colAt :: Int -> Matrix a -> [a]
colAt c m = do
r <- m
return (r !! c)
这里的问题现在很明显。在正确的实现中需要 m ,然后对于每个项目 r <- m依次找到元素 r !! c :: a , 将它包装在一个列表中,然后返回它。相比之下,您的实现提取每个项目 r <- m正确,然后尝试提取“列表”中的每个“元素” r !! c :: a ——这实际上不一定是一个列表,给出了你看到的类型错误。修复很简单:在正确的实现中,只需添加一个 return , 给 [ e | r <- m, e <- return (r !! c) ] .或者,更简单地说,使用 [x | x <- return l] 的事实与 [l] 相同,您可以更简单地将其重写为 [ r !! c | r <- m ] .

关于Haskell 列表理解和列表 Monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65748449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com