具有$的Haskell局部函数应用程序 [英] Haskell partial function application with $

查看:69
本文介绍了具有$的Haskell局部函数应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是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.

看类型,这很有意义-它只需要bNum类型值:

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.

这是我的问题:

  1. 这是怎么回事?
  2. 约束Num (a -> b)语法是什么意思?
  3. 以这种方式使用($)的示例是什么,以($) (2)之类的东西开头?
  1. What's happening here?
  2. What does the constraint Num (a -> b) syntax mean?
  3. 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 an Integer.

另一方面,($)具有类型

> :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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆