当前位置:  开发笔记 > 编程语言 > 正文

使用'if'进行无效的函数

如何解决《使用'if'进行无效的函数》经验,为你挑选了3个好方法。

我在Haskell有一个任务(不,这不是我的功课,我正在学习考试).

任务是:

写入无点函数numocc,用于计算给定列表中元素的出现次数.例如:numocc 1 [[1, 2], [2, 3, 2, 1, 1], [3]]=[1, 2, 0]

这是我的代码:

addif :: Eq a => a -> Int -> a -> Int
addif x acc y = if x == y then acc+1 else acc

count :: Eq a => a -> [a] -> Int
count = flip foldl 0 . addif

numocc :: Eq a => a -> [[a]] -> [Int]
numocc = map . count

numocc并且count是'无点',但他们使用的功能addif不是.

我不知道如何才能完成无addif点功能.有什么办法可以if免费提供声明吗?也许有一个使用不的技巧if



1> bheklilr..:

我会用事实,你可以很容易地转换成一个Bool一个来Int使用fromEnum:

addif x acc y = acc + fromEnum (x == y)

现在你可以开始应用通常的技巧使其无点

-- Go prefix and use $
addif x acc y = (+) acc $ fromEnum $ (==) x y
-- Swap $ for . when dropping the last argument
addif x acc = (+) acc . fromEnum . (==) x

等等.我不会带走让它免费的所有乐趣,特别是当有工具为你做的时候.

或者,您可以编写类似的函数

count x = sum . map (fromEnum . (==) x)

这几乎是免费的,并且有一些技巧可以让你更接近,尽管它们很快变得非常讨厌:

count = fmap fmap fmap sum map . fmap fmap fmap fromEnum (==)

在这里,我认为它实际上看起来更好用fmap而不是(.),虽然你可以替换每一个fmap,(.)它将是完全相同的代码.从本质上讲,(fmap fmap fmap)如果你给它起名字,.:你可以把它写成一个单个参数和一个两个参数函数

count = (sum .: map) . (fromEnum .: (==))

细分:

> :t fmap fmap fmap sum map
Num a => (a -> b) -> [a] -> b

所以它需要一个函数从b一个数字a,一个bs 的列表,并返回一个a,不是太糟糕.

> :t fmap fmap fmap fromEnum (==)
Eq a => a -> a -> Int

这种类型可以写成Eq a => a -> (a -> Int),这是一个值得注意的重要事项.这使得该函数的返回类型的输入匹配fmap fmap fmap sum mapb ~ Int的,所以我们可以撰写他们得到类型的函数Eq a => a -> [a] -> Int.



2> Will Ness..:

为什么不

numocc x 
  = map (length . filter (== x))
  = map ((length .) (filter (== x)) )
  = map (((length .) . filter) (== x))
  = map (((length .) . filter) ((==) x))
  = map (((length .) . filter . (==)) x)
  = (map . ((length .) . filter . (==))) x
  = (map . (length .) . filter . (==)) x

然后是琐碎的eta收缩.



3> Bergi..:

一个技巧是导入众多if功能中的一个,例如Data.Bool.bool 1 0(也见于Data.Bool.Extras).

一个更神秘的技巧是使用Foreign.Marshal.Utils.fromBool,这正是你需要的.或者同样的事情,减少奥术:( fromEnum谢谢@bheklilr).

但我认为最简单的方法就是简单地避免计算自己,然后lengthfilter输入数字之后应用标准函数.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有