J C*_*per 4 haskell type-inference typeclass
通常看来以下是非法的:
class Foo a where
foo :: a -> b -> a
Run Code Online (Sandbox Code Playgroud)
这是有道理的; 我们怎么知道是什么b?
但是,如果我们看看Functor的定义:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
我们看到a并b显示,即使我们只指定f为类型变量.我猜这是允许的,因为编译器看到例如f a并且可以发现它f本身必须采用a,所以a在我们的Functor定义中使用它是安全的.我对么?
让我们分别看一下每一行.
class Functor f where
Run Code Online (Sandbox Code Playgroud)
这声明了一个名为的单参数类型类Functor; 将调用满足它的类型f.
fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
像任何函数定义一样,所有自由类型变量都是隐式forall编辑的 - 它们可以被任何东西替换.但是,由于第一行,f在范围内.因此,fmap具有类型签名fmap :: forall a b. Functor f => (a -> b) -> f a -> f b.换句话说,每个仿函数都需要有一个定义,fmap哪个可以适用于任何 a和b,并且f必须有类型(类型的类型)* -> *; 即,它必须是这样一种类型,需要另一种类型,如[]或Maybe或IO.
你说的话是不正确的; 这a不是特别的,如果我们有另一个功能Functor,它将看不到相同a或b.但是,编译器确实使用该f a位来确定f必须是什么类型.此外,您的Foo课程完全合法; 我可以指定一个实例如下
instance Foo (a -> b) where
foo f _ = f
Run Code Online (Sandbox Code Playgroud)
这满足foo :: a -> b -> a了所有 b ; 请注意,bin Foo (a -> b)是不同的.不可否认,这不是一个非常有趣的例子,但它完全合法.
| 归档时间: |
|
| 查看次数: |
343 次 |
| 最近记录: |