gpt4 book ai didi

haskell - 使函数与 'if' 无点

转载 作者:行者123 更新时间:2023-12-03 23:21:40 25 4
gpt4 key购买 nike

我在 Haskell 中有一个任务(不,这不是我的作业,我正在为考试而学习)。

任务是:

Write point-free function numocc which counts occurrences of element in given lists. For example: 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
numocccount是“无点”,但他们正在使用函数 addif不是。

我不知道如何执行 addif 功能免积分。有什么办法吗 if声明点免费?也许有一个使用 no if 的技巧?

最佳答案

我会使用您可以轻松转换 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 获取一个函数到数字 ab 的列表s,并返回 a ,还不错。
> :t fmap fmap fmap fromEnum (==)
Eq a => a -> a -> Int

而这个类型可以写成 Eq a => a -> (a -> Int) ,这是需要注意的重要一点。这使得该函数的返回类型与 fmap fmap fmap sum map 的输入相匹配。与 b ~ Int , 所以我们可以将它们组合成 Eq a => a -> [a] -> Int 类型的函数.

关于haskell - 使函数与 'if' 无点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34342516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com