我一直在阅读Gabriel Gonzale关于Free Monads的出色博客文章。为了帮助我理解,我想为以下类型创建Show实例并在GHCi中对其进行处理,该类型(来自博客文章)为:
data Thread m r = Atomic (m (Thread m r)) | Return r
Run Code Online (Sandbox Code Playgroud)
我的Show实例是:
instance (Show m, Show r) => Show (Thread m r) where
show (Atomic m x) = "Atomic " ++ show m ++ " " ++ show x
show (Return x) = "Return " ++ show x
Run Code Online (Sandbox Code Playgroud)
不幸的是,当尝试加载文件时,GHCi给了我这个错误:
• Expected kind ‘* -> *’, but ‘m’ has kind ‘*’
• In the first argument of ‘Thread’, namely ‘m’
In the first argument of ‘Show’, namely ‘Thread m r’
In the instance declaration for ‘Show (Thread m r)’
Run Code Online (Sandbox Code Playgroud)
因此,最重要的是:此错误是什么意思,我为什么会得到它?我认为回答该问题将极大地帮助我理解该博客文章(尽管以稍微绕行的方式)。此外,可以正常运行的Show实施会是什么样子?我尝试为Either查看实例,但不知道发生了什么。
根据Thread m r = Action (m (Thread m r) | …,m是接受一个类型并返回另一个类型的东西。我们称m类型构造器或种类构造器* -> *。另一个类似的例子是Maybe:
data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)
Maybe它本身不是一种类型。您必须提供其他类型,例如Maybe Int或Maybe String。
现在Show期望一个类型为kind *。但是Thread需要* -> *。因此,GHC放弃了。自从Show m出现之前Thread m r,GHC认为它的类型是*,不适用于Action (m (Thread m r)),因为这将需要类型构造函数(* -> *)。
顺便说一句,这个问题就是为什么类似的类Show1存在于某些软件包中的原因。您可以采用它,然后编写您的Show实例:
instance (Show1 m, Show r) => Show (Thread m r) where
show (Atomic x) = "Atomic " ++ show1 x
show (Return x) = "Return " ++ show x
Run Code Online (Sandbox Code Playgroud)
或者,您可以深入研究不确定实例的领域,并说Thread m r可以显示(如果m (Thread m r)可以显示):
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
instance (Show r, Show (m (Thread m r))) => Show (Thread m r) where
show (Atomic x) = "Atomic " ++ show x
show (Return x) = "Return " ++ show x
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
332 次 |
| 最近记录: |