在"了解你一个Haskell"一书中,第11章我们介绍了newtype关键字,这一切对我来说都是有意义的,我们看到将Pair类型作为Functor的一个实例.
本讨论以一个问题陈述开始,即"只有一个参数的类型构造函数可以成为Functor的一个实例".我不明白这个说法.这个限制在哪里描述过?
在讨论的上下文中,我们有一个类型对定义为:
newtype Pair b a = Pair { getPair :: (a,b) }
Run Code Online (Sandbox Code Playgroud)
鉴于此,我本以为我们可以使用类似的东西:
instance Functor (Pair a b) where ...
Run Code Online (Sandbox Code Playgroud)
我原以为(Pair ab)会在Functor的定义中替换'f'而没有任何问题.什么阻止这种工作?
接下来,作者继续使用以下方法使Pair成为Functor的实例:
instance Functor (Pair c) where ...
Run Code Online (Sandbox Code Playgroud)
这是我迷路的地方.我不记得曾经在类型构造函数中看到"部分应用"类型.我不确定在这种情况下这甚至意味着什么,更不用说它如何解决上面提到的问题.
我想我在某个地方有一种误解,但我不知道该去哪里寻找它.我确实找到了这个答案,但它似乎只是回答这个问题的一部分.
"只有一个参数的类型构造函数才能成为Functor的一个实例." 我不明白这个说法.这个限制在哪里描述过?
限制来自fmap定义中的类型Functor:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
由于类变量f应用于一个参数f a,因此用于实例化的类型Functor必须能够采用一个参数.由于应用程序f a是函数类型的一部分,f因此不能使用多个参数.(还有一个更微妙的部分是关于f在这里指定了什么类型的参数,但我认为现在值得跳过它;希望你的教程稍后会触及这个细微之处.)
鉴于此,我本以为我们可以使用类似的东西:
Run Code Online (Sandbox Code Playgroud)instance Functor (Pair a b) where ...我原以为(Pair ab)会在Functor的定义中替换'f'而没有任何问题.什么阻止这种工作?
它再次成为fmap阻止这种工作的类型.填补Pair c d了f(修改a,以c和b以d避免名称冲突),我们会得到
fmap :: (a -> b) -> Pair c d a -> Pair c d b
Run Code Online (Sandbox Code Playgroud)
这没有多大意义.
这是我迷路的地方.我不记得曾经在类型构造函数中看到"部分应用"类型.
嗯......现在你有了.=)
我不确定在这种情况下这甚至意味着什么,更不用说它如何解决上面提到的问题.
这意味着在术语级别的部分应用程序基本相同:Pair a类似于将另一种类型作为参数的类型函数.因此,例如,Pair a应用于Int给出Pair a Int类型.它解决了这个问题,因为现在我们提供了一个"类型函数"的东西,而不是"类型"的东西,所以将它应用到另一种类型是有道理的; 即,取代类型fmap为一个Pair c实例将是
fmap :: (a -> b) -> Pair c a -> Pair c b
Run Code Online (Sandbox Code Playgroud)
现在有意义,因为Pair c a并且Pair c b是明智的类型,而之前Pair c d a和Pair c d b过度应用,因此不是明智的类型.
| 归档时间: |
|
| 查看次数: |
213 次 |
| 最近记录: |