不同lambda函数和字符的含义

时间:2016-11-17 19:15:38

标签: haskell lambda syntax

目前我正在学习Haskell,但我正在努力学习一些例子的语法。他们究竟是什么意思?

首先:这两个lambdas(-> \yy)有什么区别?

lambda1 = \x -> \y -> x + y
lambda2 = \x y -> x + y

第二:这是什么意思?这是一个充当“伪”列表生成器的lambda,它生成一个包含3个元素的列表。我该如何创建这样的列表?

lambda3 = [\x -> x+1, \x -> 2*x, \x -> x^2]

第三次\_究竟意味着什么?

lambda4 = \_ -> (\x -> x+1, \() -> 'a')

4 个答案:

答案 0 :(得分:10)

lambda2lambda1的语法糖。所有这些都是等价的:

f = \x -> \y -> x + y
f = \x y -> x + y
f x = \y -> x + y
f x y = x + y
f x y = (+) x y
f x = (+) x
f = (+)

lambda3是数字上的一元函数列表。每个函数都有(Num a) => a -> a类型,因此列表的类型为(Num a) => [a -> a]。您可以使用map或列表推导来生成一个值列表:

fs = [\x -> x+1, \x -> 2*x, \x -> x^2]

map (\f -> f 3) fs
map ($ 3) fs
[f 3 | f <- fs]
==
[4, 6, 9]

lambda4使用模式匹配语法。例如,如果您有数据类型:

data Foo = Foo Int String

然后你可以编写一个模式匹配的lambda:

f = \ (Foo n s) -> concat (replicate n s)

f (Foo 3 "bar") == "barbarbar"

(但与case不同,如果Foo有多个构造函数,则无法提供替代模式。)

_模式只是说“接受一个值而忽略它”,所以lambda4是一个接受参数的函数,忽略它,并返回一对(2元组)的一元函数,类型(Num a) => a -> a的第一个和() -> Char类型的第二个,因此其类型为Num a => r -> (a -> a, () -> Char)

lambda4 = \_ -> (\x -> x+1, \() -> 'a')
lambda4 = \ignored -> (\x -> x+1, \() -> 'a')

(inc, getA) = lambda4 ()
inc 3 == 4
getA () == 'a'

忽略其参数的函数可以使用const函数构造,而运算符部分((+ 1))通常优先于lambdas(\x -> x + 1),因此您也可以编写以上内容为:

lambda4 = const ((+ 1), const 'a')

答案 1 :(得分:3)

  

首先:这两个lambdas之间有什么区别( - &gt; \ y和y)?

没有区别。两者都为同一输入产生相同的输出,并且由于它们是纯函数,因此可以确保它们不会产生您看不到的外部效果。

不同之处在于第一个lambda使用currying的语法糖。 var min = arr.SelectMany((subArr, i) => subArr.Select((value, j) => new { i, j, value })) .OrderBy(x => x.value) .First(); int firstIndex = min.i; int secondIndex = min.j; 等于\x y -> x + y。现在,你不觉得它看起来很像类型签名,比如\x -> \y -> x + y吗? ;) 这意味着函数foo :: Int -> Int -> Int需要2 foo并生成Int

因为我对第二个问题没有一个非常准确的答案......

  

第三:Int究竟意味着什么?

这是与\_变量关联的lambda函数(\)。 _用作占位符,表示“我不关心此变量的内容,我甚至会给它一个正确的名称”。

答案 2 :(得分:3)

关于第二个问题,lambda3只是一个糟糕的变量名称。这是Num a => a -> a类型的函数列表。您可以通过在ghci中键入以下内容来验证:

:t [\x -> x+1, \x -> 2*x, \x -> x^2]

答案 3 :(得分:0)

没有-> y。阅读本文的正确方法是

(\ x -> (\ y -> (x + y)))

碰巧,Haskell有#34; curried函数&#34;,这意味着

\ x y -> (x + y)

恰好与上述相同。

lambda3是一个包含三个元素的列表。这些元素中的每一个都恰好是一个功能。函数是Haskell中的数据;你可以将它们作为参数传递,将它们作为结果返回,将它们填入列表等等。

lambda3 = [ (\x -> x+1) , (\x -> 2*x) , (\x -> x^2) ]
lambda4 = \_ -> (\x -> x+1, \() -> 'a')

&#34; _&#34;性格基本上意味着&#34;我不在乎这是什么;忽略它&#34;。您可以在任何可以使用模式的地方使用它。例如,

foobar x _ z = x + y

是一个3参数函数,完全忽略参数#2。阅读模式匹配,这应该变得清晰。 (即,它不与lambdas有关,它与模式有关。)