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)