如何在一行中编写长度函数?
How can I write the length function in one line?
编辑为什么对大学教程 Q 投反对票?
教程问题是为列表的长度编写单行函数一个数组。
单行函数的示例就是这种类型的表达式。 这个例子中的具体函数不相关,只是它使用匿名函数(我认为),使用 where
语法并且全部在一行上
f = f' where f' 1 = 0; f' x = x + f' (x-1)
我无法解决,但想知道一些方法。
更新: 现在您已经提供了问题的背景,查看您现在包含的页面,它已经为您提供了所有的解决方案——它是只是一个打字练习。输入您自己的代码 很重要,因为这样我们学得更好。因此解决方案是:
leng1 lst = if lst==[] then 0 else let { x:xs = lst } in ...
leng2 lst | lst==[] = ... | otherwise = ...
leng3 lst = f lst where f [] = 0 ; f ... = ...
此外,页面上关于双子句定义的说法是不正确的。它也可以在一行中输入,也可以用 ;
分隔子句:
leng0 [] = 0 ; leng0 (x:xs) = 1 + leng0 xs
当您在一行中输入它们时,它们都会起作用,就像页面告诉您的那样。
(是的,与页面上的代码相比,您可能需要那些额外的 {}
和 ()
才能工作)。
(原版答案如下:)
数组length
的一行实现:
lenArr = succ . negate . uncurry (-) . bounds
列表length
的一行实现:
lenLs = \ xs -> sum [1 | _x <- xs]
= getSum . foldMap (\ _x -> Sum 1)
= flip (foldr (\ _x r i -> r $! (i+1)) id) 0
= flip (foldr ((.) . const (+1)) id) 0
= flip (foldr ((.) . const (+1)) (const 0)) ()
= foldr ((+) . const (1)) 0
= foldr (($) . const (+1)) 0
= foldr ($) 0 . (succ <$)
= \ xs -> let {ys = 0 : zipWith (\ a b -> a+1) ys xs} in last ys
= last . scanl (\ a b -> a+1) 0
= foldl (\ a b -> a+1) 0
= foldl' (\ a b -> a+1) 0
= ...
编辑为什么对大学教程 Q 投反对票?
教程问题是为列表的长度编写单行函数一个数组。
单行函数的示例就是这种类型的表达式。 这个例子中的具体函数不相关,只是它使用匿名函数(我认为),使用 where
语法并且全部在一行上
f = f' where f' 1 = 0; f' x = x + f' (x-1)
我无法解决,但想知道一些方法。
更新: 现在您已经提供了问题的背景,查看您现在包含的页面,它已经为您提供了所有的解决方案——它是只是一个打字练习。输入您自己的代码 很重要,因为这样我们学得更好。因此解决方案是:
leng1 lst = if lst==[] then 0 else let { x:xs = lst } in ...
leng2 lst | lst==[] = ... | otherwise = ...
leng3 lst = f lst where f [] = 0 ; f ... = ...
此外,页面上关于双子句定义的说法是不正确的。它也可以在一行中输入,也可以用 ;
分隔子句:
leng0 [] = 0 ; leng0 (x:xs) = 1 + leng0 xs
当您在一行中输入它们时,它们都会起作用,就像页面告诉您的那样。
(是的,与页面上的代码相比,您可能需要那些额外的 {}
和 ()
才能工作)。
(原版答案如下:)
数组length
的一行实现:
lenArr = succ . negate . uncurry (-) . bounds
列表length
的一行实现:
lenLs = \ xs -> sum [1 | _x <- xs]
= getSum . foldMap (\ _x -> Sum 1)
= flip (foldr (\ _x r i -> r $! (i+1)) id) 0
= flip (foldr ((.) . const (+1)) id) 0
= flip (foldr ((.) . const (+1)) (const 0)) ()
= foldr ((+) . const (1)) 0
= foldr (($) . const (+1)) 0
= foldr ($) 0 . (succ <$)
= \ xs -> let {ys = 0 : zipWith (\ a b -> a+1) ys xs} in last ys
= last . scanl (\ a b -> a+1) 0
= foldl (\ a b -> a+1) 0
= foldl' (\ a b -> a+1) 0
= ...