gpt4 book ai didi

haskell - Pointfree 版本无法编译,但有针对性的版本可以吗?

转载 作者:行者123 更新时间:2023-12-04 13:50:01 25 4
gpt4 key购买 nike

我想编写一个 Haskell 函数,它返回一个附加到自身计数时间的列表(如 Python 中的 lst * count)。

我的第一次尝试是:

self_append_n :: Int -> [a] -> [a]
self_append_n = concat . replicate

我的理由是 replicate接受一个计数和一个值,并生成一个值列表。当值本身是一个列表时,剩下的就是将这些列表连接在一起。但是,这会产生一个令人困惑的错误:
Couldn't match type `[a0]' with `[a] -> [a]'
Expected type: [[a0]] -> [a] -> [a]
Actual type: [[a0]] -> [a0]
In the first argument of `(.)', namely `concat'
In the expression: concat . replicate
In an equation for `self_append_n':
self_append_n = concat . replicate

然后我写了一个有意义的版本:
self_append_n a b = concat $ replicate a b

它有效!

为什么免点版本编译失败,加点就可以了?

最佳答案

明确地将签名括起来可能会有所帮助:

selfAppend :: Int -> ([a]         -> [a])
replicate :: Int -> ([a]->[[a]])
concat :: [[a]] -> [a]

如果您尝试撰写 concat . replicate ,你最终给了 concat replicate 的部分应用结果,即 [a] -> [[a]] .这与 [[a]] 不一致.

您需要做的是首先将两个参数传递给 replicate在交出结果之前。 IMO 最好的方法是“半无点”:
selfAppend n = concat . replicate n

可读性较差的替代方案是
selfAppend' = curry $ concat . uncurry replicate
selfAppend'' = (concat.) . replicate

或与臭名昭著的运营商
(.:) :: (c->d) -> (a->b->c) -> a->b->d
(.:) = (.).(.)
-- `≡ fmap fmap fmap`, also a popular implementation...

你可以简单地写
selfAppend''' = concat .: replicate

关于haskell - Pointfree 版本无法编译,但有针对性的版本可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25596103/

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