Reflection 哈斯克尔:为什么要检查这种类型?
这是从Reflection-0.5中获得的一个最小示例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
{-# 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
。谢谢本。我错过了中缀和前缀符号,但现在清楚了!