如何在一行中编写长度函数?

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
      = ...