我如何在 Idris interactive 中评估这个递归函数?
How do I evaluate this recursive function in Idris interactive?
涉足 Idris,我试图将 this Haskell function 移植到 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)
但是,当我在交互式 idris 中调用它时,似乎只对函数的第一次调用进行了评估,而递归的下一步则没有。这是我在控制台上得到的。
*hello> windowl 2 [1,2,3,4,5]
[1, 2] :: Main.windowl, loop Integer 2 [2, 3, 4, 5] : List (List Integer)
有人可以告诉我发生了什么以及我如何才能完全评估函数吗?
如 manual 中所述:
At compile-time it [Idris] will only evaluate things which it knows to be total
... [skipped]...
The REPL, for convenience, uses the compile-time notion of evaluation.
完整性检查器无法发现 windowl
函数实际上是完整的,因此我们可以使用 assert_smaller
construction:
total
windowl : Nat -> List a -> List (List a)
windowl size = loop
where
loop : List a -> List (List a)
loop xs = case List.splitAt size xs of
(ys, []) => if length ys == size then [ys] else []
(ys, _) => ys :: loop (assert_smaller xs $ drop 1 xs)
或更改 loop
以使完整性对完整性检查器显而易见:
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)
涉足 Idris,我试图将 this Haskell function 移植到 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)
但是,当我在交互式 idris 中调用它时,似乎只对函数的第一次调用进行了评估,而递归的下一步则没有。这是我在控制台上得到的。
*hello> windowl 2 [1,2,3,4,5]
[1, 2] :: Main.windowl, loop Integer 2 [2, 3, 4, 5] : List (List Integer)
有人可以告诉我发生了什么以及我如何才能完全评估函数吗?
如 manual 中所述:
At compile-time it [Idris] will only evaluate things which it knows to be total ... [skipped]... The REPL, for convenience, uses the compile-time notion of evaluation.
完整性检查器无法发现 windowl
函数实际上是完整的,因此我们可以使用 assert_smaller
construction:
total
windowl : Nat -> List a -> List (List a)
windowl size = loop
where
loop : List a -> List (List a)
loop xs = case List.splitAt size xs of
(ys, []) => if length ys == size then [ys] else []
(ys, _) => ys :: loop (assert_smaller xs $ drop 1 xs)
或更改 loop
以使完整性对完整性检查器显而易见:
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)