我正在尝试使用Haskell中的scanl
函数。我已经缩小了我的问题,可以在以下两种情况下描述,这可以在解释器中使用包含scanl
的Haskell中的普通库运行(注意,我不一定对Monadic值感兴趣,但只是如何使用scanl
来确保类型一致性):
为什么下面的工作与预先列出的Right value
s工作:
*Defs> scanl (\x acc -> x ++ acc) [] [[(Right 1)], [(Right 2)]]
[[],[Right 1],[Right 1,Right 2]]
当这不起作用并导致以下错误消息时:
*Defs> scanl (\x acc -> [x] ++ acc) [] [(Right 1), (Right 2)]
<interactive>:36:35: error:
* Couldn't match expected type `[[a]]'
with actual type `Either a0 b0'
...
2条答案
按热度按时间v6ylcynt1#
我想你已经交换了值和累加器。考虑
scanl
的类型:累加器值的类型为
b
。它是第一位的。如果在第二个示例中交换参数,它可以工作:
你也可以交换第一个例子的参数,这也是可行的:
lnvxswe22#
你在这里要做的已经存在,这是**
inits :: [a] -> [[a]]
**,它产生所有前缀。您使用列表列表,但可以通过连接而不是假装来处理。然而,每次构造一个新的列表,在右端追加,都需要*(n2),这是有意义的,因为总的构造确实是(n2)。但是,例如,我们可能只想生成最后一个列表。
因此,使用 difference list 可能会更好,它允许在 (1) 中添加一个元素,因此如果我们只想构造最后一个元素之一,最终只需要(n2)* 时间。
所以我们可以构造函数为: