Haskell 如何在Idris interactive中计算此递归函数?
涉猎伊德里斯,我试图向伊德里斯移植。我想我成功了,用这个密码Haskell 如何在Idris interactive中计算此递归函数?,haskell,recursion,idris,Haskell,Recursion,Idris,涉猎伊德里斯,我试图向伊德里斯移植。我想我成功了,用这个密码 windowl : Nat -> List a -> List (List a) windowl size = loop where loop xs = case List.splitAt size xs of (ys, []) => if length ys == size then [ys] else [] (ys, _) => ys :: loop (drop 1 xs
windowl : Nat -> List a -> List (List a)
windowl size = loop
where
loop xs = case List.splitAt size xs of
(ys, []) => if length ys == size then [ys] else []
(ys, _) => ys :: loop (drop 1 xs)
但是,当我在interactive idris中调用它时,似乎只对函数的第一次调用求值,而递归的下一步不求值。这是我在控制台上看到的
*hello> windowl 2 [1,2,3,4,5]
[1, 2] :: Main.windowl, loop Integer 2 [2, 3, 4, 5] : List (List Integer)
有人能告诉我发生了什么,以及我如何才能完全评估函数吗?如中所述:
在编译时,它[Idris]将只评估它知道是全部的东西
... [跳过]。。。
为了方便起见,REPL使用编译时的求值概念
总计检查器无法发现windowl
函数实际上是总计,因此我们可以使用assert\u较小的
进行欺骗:
或者更改循环
,以使总体检查程序能够明显看到总体:
total
windowl : Nat -> List a -> List (List a)
windowl size = loop
where
loop : List a -> List (List a)
loop [] = []
loop xs@(x :: xs') = case List.splitAt size xs of
(ys, []) => if length ys == size then [ys] else []
(ys, _) => ys :: loop xs'
是的,我在这里走捷径,用模式匹配来代替硬编码的drop 1
,以说明这个想法。更一般的情况可能需要更多的工作
此时,REPL将对表达式进行完全求值:
λΠ> windowl 2 [1,2,3,4,5]
[[1, 2], [2, 3], [3, 4], [4, 5]] : List (List Integer)
婴儿步,安东:)
λΠ> windowl 2 [1,2,3,4,5]
[[1, 2], [2, 3], [3, 4], [4, 5]] : List (List Integer)