- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
总的来说,我对 Haskell 和 FP 很陌生。我已经阅读了许多描述什么是柯里化的文章,但我还没有找到解释它实际上是如何工作的。
这是一个函数:(+) :: a -> (a -> a)
如果我这样做 (+) 4 7
, 函数取 4
并返回一个接受 7
的函数并返回 11
.但是4
会发生什么? ?第一个函数对 4
有什么作用? ?什么(a -> a)
做 7
?
当我想到一个更复杂的函数时,事情变得更加困惑:
max' :: Int -> (Int -> Int)
max' m n | m > n = m
| otherwise = n
(Int -> Int)
比较它的参数?只需要一个参数,但需要两个参数来做
m > n
.
最佳答案
理解高阶函数
Haskell 作为一种函数式语言,支持高阶函数 (HOF)。在数学中 HOF 被称为 functionals ,但你不需要任何数学来理解它们。在通常的命令式编程中,就像在 Java 中一样,函数可以接受值,比如整数和字符串,对它们做一些事情,然后返回某个其他类型的值。
但是,如果函数本身与值没有区别,并且您可以接受一个函数作为参数或从另一个函数返回它呢? f a b c = a + b - c
是一个无聊的函数,它求和 a
和 b
然后减去 c
.但是这个函数可能更有趣,如果我们可以概括它,如果我们有时想要求和 a
怎么办?和 b
,但有时会成倍增加?或除以 c
而不是减去?
记住,(+)
只是一个返回一个数字的 2 个数字的函数,它没有什么特别的,所以任何返回一个数字的 2 个数字的函数都可以代替它。写作 g a b c = a * b - c
, h a b c = a + b / c
等等只是不适合我们,我们需要一个通用的解决方案,毕竟我们是程序员!这里是如何在 Haskell 中完成的:
let f g h a b c = a `g` b `h` c in f (*) (/) 2 3 4 -- returns 1.5
let g f n = (\m -> m `f` n); f = g (+) 2 in f 10 -- returns 12
(\m -> m `f` n)
构造是一个
anonymous function共 1 个参数
m
适用
f
到那个
m
和
n
.基本上,当我们拨打
g (+) 2
时我们创建了一个只有一个参数的函数,它只将收到的任何内容加 2。所以
let f = g (+) 2 in f 10
等于 12 和
let f = g (*) 5 in f 5
等于 25。
(+)
.
f n = (\m -> n - m)
g = f 10
g 8 -- would return 2
g 4 -- would return 6
:t (++)
在解释器中,其中
(++)
是一个将 2 个字符串连接在一起的函数,它将返回
(++) :: [a] -> [a] -> [a]
.类型不是
[a],[a] -> [a]
,但是
[a] -> [a] -> [a]
, 意思是
(++)
接受一个列表并返回一个
[a] -> [a]
类型的函数.这个新函数可以接受另一个列表,它最终会返回一个类型为
[a]
的新列表。 .
f a b c
使用 Python 或 Java 的
f(a, b, c)
.这不是什么奇怪的审美决定,在 Haskell 函数应用程序从左到右,所以
f a b c
实际上是
(((f a) b) c)
,这是完全有道理的,一旦你知道
f
默认是柯里化的。
[a] -> [a] -> [a]
相当于
[a] -> ([a] -> [a])
.它们在 Haskell 中是一回事,Haskell 对待它们完全一样。这是有道理的,因为当你只应用一个参数时,你会得到一个
[a] -> [a]
类型的函数。 .
map
的类型:
(a -> b) -> [a] -> [b]
,它接收一个函数作为它的第一个参数,这就是它有括号的原因。
(+)
(+) 2
(+) 2 3
map
map (\x -> head x)
map (\x -> head x) ["conscience", "do", "cost"]
map head
map head ["conscience", "do", "cost"]
(\x -> replicate 3 x)
你可以写
(replicate 3)
.但是如果你想有一个除法怎么办
(/)
运算符而不是
replicate
?对于中缀函数,Haskell 允许您使用任一参数部分应用它。
(2/)
相当于
(\x -> 2 / x)
和
(/2)
相当于
(\x -> x / 2)
.使用反引号,您可以获取任何二元函数的一部分:
(2`elem`)
相当于
(\xs -> 2 `elem` xs)
.
(+^)
是一些对 4 个参数求和的奇怪函数,然后
let (+^) a b c d = a + b + c in (2+^) 3 4 5
返回 14。
(.)
链一起发挥作用。应用运营商
($)
只是将左侧的函数应用于右侧的参数,所以
f $ x
相当于
f x
.然而
($)
在所有运算符中优先级最低,所以我们可以用它来去掉括号:
f (g x y)
相当于
f $ g x y
.
map ($2) [(2+), (10-), (20/)]
将产生
[4,8,10]
.
(f . g . h) (x + y + z)
,
f (g (h (x + y + z)))
,
f $ g $ h $ x + y + z
和
f . g . h $ x + y + z
是等价的,但
(.)
和
($)
是不同的东西,所以阅读
Haskell: difference between . (dot) and $ (dollar sign)和
parts from Learn You a Haskell了解差异。
关于haskell - 柯里化(Currying)是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6652234/
export const postMoviePopular = url = dispatch => { const data = axios.get(url); dispatch(sa
我一直在学习 Haskell 中的柯里化(Currying),现在尝试以柯里化(Currying)形式编写函数的 Haskell 类型签名,其非柯里化(Currying)形式有一个 (x, y) 类型
在许多列表处理语言(以及其他语言)中,它们都有一个名为 curry 的函数,它可以完成一些巧妙的事情。我的问题是为什么他们称之为 curry ?这个名字从何而来?我唯一的猜测是来自世界各国的美味 cu
当前的 curry 函数采用接受 2 个元素的元组的函数,并允许对结果函数进行 curry 或部分应用。 let x = curry (\(x, y) -> x + y) x 1 2 -- 3 是否可
假设我有 library(functional) f = function(x, p) { x^p } f2 = Curry(f, p=2) 有没有办法找出仅给定 f2 的 p 被设置为什么? 最佳答
我试图了解柯里化(Currying)相对于 Scala 中部分应用程序的优势。请考虑以下代码: def sum(f: Int => Int) = (a: Int, b: Int) => f(a)
我有一个函数,我必须包装另一个函数(如果它存在)或替换它(如果它不存在)。这意味着参数的数量会根据情况而变化。 这就是我的意思- 列列表: const myColumns = [ {name:
我不明白为什么在无类型的 lambda 演算中允许以下 beta 减少: (λx.x y) (u v) -> ((u v) y) 具体来说,我无法理解如何传递两个参数 u和 v到单个参数 x在 λx.
Ruby 1.9's built in support of currying支持两种处理带有任意数量参数的过程的方法: my_proc = proc {|*x| x.max } 1) curry 没
根据下面的代码片段,example-func-A 和 example-func-B 之间是否存在任何有意义的区别? #lang racket/base (require (only-in racket
我是 JavaScript 的新手,试图理解 Oreilly JavaScript Cookbook 中有关柯里化(Currying)的教程。 谁能用通俗易懂的语言逐步详细解释这个程序。请务必解释在程
所以我知道你可以: > f = map (+1) > f [1,2,3] [2,3,4] 但是,如果您这样做会怎样: > g = map (+) [1,2,3] > :t g g :: Num a =
我在多篇文章和博客中看到过对柯里化(Currying)函数的引用,但我找不到一个好的解释(或者至少是一个有意义的解释!) 最佳答案 柯里化(Currying)是指将一个接受多个参数的函数分解为一系列函
所以我在我们的教科书中经过一些反复试验和研究后得到了以下功能,我可以想出一个解决方案。 def prodC1(f : Int => Int) : (Int, Int) => Int = { def
我有问题,可以简化为以下示例: let func a b c = printf "%s %s %s" a b c let partial = func "a" let something_that_r
今天开始学习 Scala,我很好奇你是否可以重载一个函数来添加柯里化(Currying),比如: def add(x: Int, y: Int): Int = x + y def add(x: Int
我正在尝试编写柯里化(Currying)函数的策略,包括通用量化函数。 Require Import Coq.Program.Tactics. Definition curry1 := forall
我想以某种方式组合函数。请在伪代码(不是 F#)中考虑这两个函数 F1 = x + y F2 = F1 * 10 // note I did not specify arguments for F1,
在 Perl 6 世界中,currying 是表示部分实例化的通用术语,它也用于 (parametrized) roles 的世界。 . 但是,尚不清楚如何实际使用它: role Zipi[::T]
我想知道是否可以在多参数组函数上使用柯里化(Currying): scala> def sum(a: Int)(b: Int): Int = { a+b } sum: (a: Int)(b: Int)
我是一名优秀的程序员,十分优秀!