具有$的Haskell局部函数应用程序 [英] Haskell partial function application with $
问题描述
我是Haskell的新手,正在研究一个将函数应用程序与$
一起使用的简单示例.
I'm new to Haskell and looking at a simple example of using function application with $
.
这似乎很简单-它需要一个函数并将其应用于一个值.
It seems straightforward - it takes a function and applies it to a value.
所以这很有意义:
> (+3) $ 2
5
这也很有意义:
> ($) (+3) 2
5
这很有意义,因为第一个参数是函数,第二个参数是值.
This makes sense because the first argument is the function, and the second argument is the value.
现在考虑使用$
创建部分函数.
Now considering using $
to create a partial function.
看类型,这很有意义-它只需要b
的Num
类型值:
Looking at types, this makes sense - it just needs a Num
type value for b
:
> :t ($) (+3)
($) (+3) :: Num b => b -> b
但是这里是我迷路的地方-这里发生了什么事?:
But here's where I get lost - what is happening here?:
> :t ($) (2)
($) (2) :: Num (a -> b) => a -> b
我希望第一个参数需要是一个函数,而不是简单的Num值.
I would have expected the first argument would need to be a function, not a simple Num value.
这是我的问题:
- 这是怎么回事?
- 约束
Num (a -> b)
语法是什么意思? - 以这种方式使用
($)
的示例是什么,以($) (2)
之类的东西开头?
- What's happening here?
- What does the constraint
Num (a -> b)
syntax mean? - What's an example of using
($)
in this way, that starts with something like($) (2)
?
谢谢!
推荐答案
一方面,像2
这样的数字文字实际上被读取为fromInteger 2 :: Num a => a
,因此可以表示任何类型为Num a => a
的值,即任何类型它是类型的类Num
中的,即具有fromInteger
的特殊版本,该特殊版本定义了从整数2
转换而来的实际类型的实际值:
On the one hand, numeric literals like 2
are actually read as fromInteger 2 :: Num a => a
so can denote any value of type Num a => a
, meaning, any type which is in type class Num
, i.e. has among other things a special version of fromInteger
defined which returns the actual value of the actual type, converted from the integer 2
:
> :i Num
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
Haskell教程所述(在10.3中),
As the Haskell Tutorial puts it (in 10.3),
一个整数(不带小数点)实际上等效于将
fromInteger
应用于该数字的值作为Integer
.
An integer numeral (without a decimal point) is actually equivalent to an application of
fromInteger
to the value of the numeral as anInteger
.
另一方面,($)
具有类型
> :t ($)
($) :: (a -> b) -> a -> b
所以我们有
fromInteger 2 :: Num a1 => a1
($) :: (a -> b) -> a -> b
--------------------------------------------
($) 2 :: Num (a -> b) => a -> b
所以它是一个函数,在类Num
中也必须是.
So it's a function, which must also be in the type class Num
.
通常不是这种情况,但是Haskell不知道您是否可以导入确实定义了此类实例的某个模块:
Normally that's not the case but Haskell doesn't know if you could be importing some module which does define such an instance:
instance Num (a -> b) where
....
fromInteger n = ....
....
因此它允许在类型检查中实现这种可能性,只有到那时,看到在任何地方都没有定义这样的实际实例,它会在那个上出错.
so it allows this possibility at the type checking, and only then, seeing that there is no such actual instance defined anywhere, it errors out on that.
例如,遵循注释中 @augustss 的提示,
For example, following the hint from @augustss in the comments,
instance (Num b) => Num (a -> b) where
(+) f g x = f x + g x
(*) f g x = f x * g x
abs f x = abs (f x)
negate f x = negate (f x)
signum f x = signum (f x)
fromInteger n = const (fromInteger n)
让我们写(sin + 2 * cos^2) x
.
这篇关于具有$的Haskell局部函数应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!