Reflection 哈斯克尔:为什么要检查这种类型?

Reflection 哈斯克尔:为什么要检查这种类型?,reflection,haskell,typechecking,Reflection,Haskell,Typechecking,这是从Reflection-0.5中获得的一个最小示例 {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-} {-# OPTIONS_GHC -fno-cse -fno-full-laziness -fno-float-in #-} import Control.Applicative import Data.Proxy newtype Zero = Zero

这是从Reflection-0.5中获得的一个最小示例

{-# LANGUAGE Rank2Types, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# OPTIONS_GHC -fno-cse -fno-full-laziness -fno-float-in #-}

import Control.Applicative
import Data.Proxy

newtype Zero = Zero Zero deriving (Show)

class ReifiesNum s where
  reflectNum :: Num a => proxy s -> a

instance ReifiesNum Zero where
  reflectNum = pure 0
在GHCi中,我得到以下信息:

>:t Zero
Zero :: Zero -> Zero
这是有意义的:我要求的构造函数的类型是接受零并返回零

>:t reflectNum
reflectNum :: (ReifiesNum s, Num a) => proxy s -> a
我可以写这样的东西是有道理的

>let x = Just (undefined::Zero)
>reflectNum x
因为类型仅为零与类型变量“proxy s”匹配

最后,令人困惑的部分:

>:t (reflectNum Zero)
(reflectNum Zero) :: Num a => a
我不明白构造函数Zero::Zero->Zero的类型如何与类型变量“proxy s”匹配,但显然是匹配的,因为(reflectNum Zero)的类型只是“a”

我非常感谢您帮助我理解这个例子,并且非常感谢您提供相关概念的链接


谢谢

这只是函数arrow的中缀语法让你感到不舒服。首先,这里有一个简单易懂的例子:
可能是Int
。要使其匹配代理s,我们只需设置:

proxy = Maybe
s = Int
现在让我们假设
a->b
是编写的
funab
,因此
Zero
funzero
(即
(funzero)Zero
)。为了使其与代理服务器相匹配,我们设置:

proxy = Fun Zero
s = Zero

实际上,
proxy
(>)零
,因此
proxy s
((>)零
≡ <代码>(>)零零≡
Zero->Zero

为什么“(>)Zero”是有效类型?我无法想象我怎么能写出“>让x=[某物]::((->)零)”这样的东西。我希望我说的有道理。谢谢你的回答@Eric
(>)Zero
不是有效的类型,它是一个类型构造函数,需要应用到另一个类型以形成具体的类型。这同样适用于
可能
;没有类型
的值Maybe
,但是有类型
Maybe Int
Maybe[Double]
Maybe(Maybe(Maybe Char))
等。同样,也没有类型
(>)Zero
的值,但是有类型
(>)Zero
的值,即
Zero->Zero
。谢谢本。我错过了中缀和前缀符号,但现在清楚了!