gpt4 book ai didi

haskell - 部分应用函数和柯里化(Currying),如何制作更好的代码而不是大量的 map ?

转载 作者:行者123 更新时间:2023-12-04 16:15:56 26 4
gpt4 key购买 nike

我是 Haskell 的初学者,我正在努力掌握它。

我遇到以下问题:

我有一个获取 5 个参数的函数,可以说

f x y w z a = x - y - w - z - a

我想应用它,同时只更改变量 x来自 110y , w , za将永远是一样的。我实现的实现如下,但我认为必须有更好的方法。

假设我想使用:
x from 1 to 10
y = 1
w = 2
z = 3
a = 4

据此,我设法应用以下功能:
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])

我认为必须有更好的方法将大量缺失的参数应用于部分应用的函数,而不必使用太多的 map 。

最佳答案

到目前为止所有的建议都很好。这是另一个,起初可能看起来有点奇怪,但在许多其他情况下却非常方便。

一些类型形成运算符,如 [] ,它是映射一种元素类型的运算符,例如Int这些元素的列表类型,[Int] , 具有 Applicative 的属性.对于列表,这意味着有某种方式,由运算符 <*> 表示,发音为“应用”,将函数列表和参数列表转换为结果列表。

(<*>) :: [s -> t] -> [s] -> [t]    -- one instance of the general type of <*>

而不是您的普通应用程序,由空格或 $ 给出
($)   :: (s -> t) ->  s  ->  t

结果是我们可以用事物列表而不是事物来进行普通的函数式编程:我们有时称其为“在列表习语中编程”。唯一的其他因素是,为了应对我们的某些组件是单独的东西的情况,我们需要一个额外的小工具
pure :: x -> [x]   -- again, one instance of the general scheme

它将一个东西包装成一个列表,与 <*> 兼容.那是 pure将普通值移动到应用习语中。

对于列表, pure只创建一个单例列表和 <*>产生一个函数对一个参数的每次成对应用的结果.尤其是
pure f <*> [1..10] :: [Int -> Int -> Int -> Int -> Int]

是可以与 map f [1..10] 一起使用的函数列表(就像 <*> )再次。 f 的其余论点不是listy,所以你需要 pure他们。
pure f <*> [1..10] <*> pure 1 <*> pure 2 <*> pure 3 <*> pure 4

对于列表,这给出
[f] <*> [1..10] <*> [1] <*> [2] <*> [3] <*> [4]

即从 f 提出申请的方法列表,[1..10]、1、2、3 和 4 之一。

开幕 pure f <*> s很常见,缩写为 f <$> s , 所以
f <$> [1..10] <*> [1] <*> [2] <*> [3] <*> [4]

是通常会写的。如果可以过滤掉 <$> , pure<*>噪音,它看起来像你想到的应用程序。额外的标点符号只是必要的,因为 Haskell 无法区分一组函数或参数的列表计算与预期作为单个值但恰好是列表的非列表计算之间的区别。但是,至少,组件是按照您开始时的顺序排列的,因此您可以更轻松地看到正在发生的事情。

深奥。 (1) 在我的(不是很) private dialect Haskell,以上将是
(|f [1..10] (|1|) (|2|) (|3|) (|4|)|)

其中每个成语括号, (|f a1 a2 ... an|)表示将纯函数应用于成语中的零个或多个参数。这只是一种写作方式
pure f <*> a1 <*> a2 ... <*> an

Idris 有成语方括号,但 Haskell 没有添加它们。然而。

(2) 在具有代数效应的语言中,非确定性计算的习语(对类型检查器而言)与列表的数据类型不同,尽管您可以轻松地在两者之间进行转换。程序变成
f (range 1 10) 2 3 4

其中 range 不确定地选择给定下限和上限之间的值。因此,非确定性被视为局部副作用,而不是数据结构,它支持针对失败和选择的操作。您可以将非确定性计算包装在为这些操作赋予意义的处理程序中,并且这样的处理程序可能会生成所有解决方案的列表。也就是说,解释发生了什么的额外符号被推到了边界,而不是像那些 <*> 那样遍布整个内部。和 pure .

管理事物的边界而不是它们的内部是我们这个物种设法拥有的为数不多的好主意之一。但至少我们可以一遍又一遍地拥有它。这就是我们耕种而不是狩猎的原因。这就是为什么我们更喜欢静态类型检查而不是动态标签检查。等等...

关于haskell - 部分应用函数和柯里化(Currying),如何制作更好的代码而不是大量的 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33049909/

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