首页 > 解决方案 > 如何在一行中编写长度函数?

问题描述

编辑为什么要否决大学教程Q?

教程问题是为列表的长度编写一个单行函数数组

给出的单行函数示例就是这种类型的表达式。这个例子中的具体函数不相关,只是它使用匿名函数(我认为),使用where语法并且都在一行上

f = f' where f' 1 = 0; f' x = x + f' (x-1)

我无法解决,但想知道一些方法。

关于这个问题的课程背景

标签: haskellanonymous-function

解决方案


更新: 现在您已经提供了问题的背景,查看您现在包含的页面,它已经为您提供了所有解决方案——这只是一个打字练习。输入自己的代码重要,因为这样我们学得更好。因此解决方案是:

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

推荐阅读