与$ Haskell的部分功能应用

问题描述 投票:4回答:1

我是新来的Haskell和考虑使用的功能应用与$的一个简单的例子。

这看起来非常简单 - 它需要一个功能,并将其应用到一个值。

因此,这是有道理的:

> (+3) $ 2
5

这也有道理:

> ($) (+3) 2
5

这是有道理的,因为第一个参数是函数,第二个参数是值。

现在,使用$使局部功能的考虑。

综观类型,这是有道理的 - 它只是需要一个Num类型值b

> :t ($) (+3)
($) (+3) :: Num b => b -> b

但在这里就是我迷路了 - 这里发生了什么?:

> :t ($) (2)
($) (2) :: Num (a -> b) => a -> b

我本来期望的第一个参数需要是一个函数,而不是一个简单的民值。

因此,这里是我的问题:

  1. 这里发生了什么事?
  2. 什么是约束Num (a -> b)语法是什么意思?
  3. 是什么在这种方式使用($)的一个例子,与类似($) (2)开始?

谢谢!

haskell types polymorphism partial-application parametric-polymorphism
1个回答
9
投票

在一方面,数字文字像2实际上读作fromInteger 2 :: Num a => a这样可以表示类型Num a => a,这意味着,任何类型,是在类型类Num,即有除其他事项外fromInteger的一个特殊版本的定义返回的实际值的任何值实际类型的,从整数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

作为the Haskell Tutorial把它(10.3),

一个整数数字(不带小数点)实际上相当于fromInteger的到数字作为Integer的值的应用程序。

在另一方面,($)有型

> :t ($)
($) :: (a -> b) -> a -> b

因此,我们有

fromInteger 2 :: Num a1 =>   a1
($)           ::          (a -> b) -> a -> b
--------------------------------------------
($) 2         :: Num      (a -> b) => a -> b

所以这是一个功能,这也必须是在类型类Num

通常情况下,这不是如此,但哈斯克尔不知道,如果你可以导入一些模块,它确实定义这样的实例:

instance Num (a -> b) where
   ....
   fromInteger n = ....
   ....

因此它允许这种可能性的类型检查,也只有这样,看到有定义的任何地方没有这样的实际情况下,它的错误了这一点。

例如,下面从@augustss暗示的意见,

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

© www.soinside.com 2019 - 2024. All rights reserved.