我正在使用Data.Typeable,特别是我希望能够生成特定类型的正确类型(比方说*).我遇到的问题是TypeRep允许我们执行以下操作(使用GHC 7.8中的版本):
let maybeType = typeRep (Proxy :: Proxy Maybe)
let maybeCon = fst (splitTyConApp maybeType)
let badType = mkTyConApp maybeCon [maybeType]
Run Code Online (Sandbox Code Playgroud)
这badType在某种意义上是Maybe Maybe类型的表示,它不是任何种类的有效类型:
> :k Maybe (Maybe)
<interactive>:1:8:
Expecting one more argument to ‘Maybe’
The first argument of ‘Maybe’ should have kind ‘*’,
but ‘Maybe’ has kind ‘* -> *’
In a type in a GHCi command: Maybe (Maybe)
Run Code Online (Sandbox Code Playgroud)
我不打算在类型级别强制执行此操作,但我希望能够编写一个足够智能的程序,以避免在运行时构造此类型.我可以用数据级术语来做到这一点TypeRep.理想情况下,我会有类似的东西
data KindRep = Star | KFun KindRep KindRep
Run Code Online (Sandbox Code Playgroud)
并有一个函数kindOf与kindOf Int …
据我所知,monadic绑定操作的一个重要用途是进行变量替换,例如
do x <- maybeComputeSomething
y <- maybeComputeSomethingElse
maybeDoStuff x y
Run Code Online (Sandbox Code Playgroud)
这是一切都很好,如果maybeComputeSomething,maybeComputeSomethingElse和maybeDoStuff都返回也许值,但我觉得即使没有一个返回任何的可能性,这种形式的迭代替代的将是计算有用.由于身份是一个单子,我在某种意义上希望能够做一些事情
do x <- computeSomething
y <- computeSomethingElse
doStuff x y
Run Code Online (Sandbox Code Playgroud)
这将扩展到看起来像什么
computeSomething >>= (\x ->
computeSomethingElse >>= (\y ->
doStuff x y))
Run Code Online (Sandbox Code Playgroud)
并且因为身份monad中的绑定只是x >> = f = fx,所以这将起作用
doStuff computeSomething computeSomethingElse
Run Code Online (Sandbox Code Playgroud)
如果>> =被视为身份单子的绑定,但是这个(意料之中)失败,因为毕竟我从来没有明确地陈述一个单子(不像也许例如当类型显然是形式也许),如果哈斯克尔假定身份monad到处都是大多数情况会因所需的消歧而迅速混乱.
所以这引出了我的问题.我想要一些感觉像的代码
do x <- computeSomething
y <- computeSomethingElse
doStuff x y
Run Code Online (Sandbox Code Playgroud)
这与做同样的事情
doStuff computeSomething computeSomthingElse
Run Code Online (Sandbox Code Playgroud)
我明白,我可以通过显式定义的标识单子看上去像也许只是没有没有可能做到这一点,但是这需要一个类型 - > ID的,所以并没有真正定义身份单子.此外,我的函数现在必须有类型a - > Id b,而我真的希望它们仍然是a - > b的形式.有没有办法在不引入所涉及类型的复杂性的情况下创建重复的替换感觉?