类型操作符和类型要求的顺序

时间:2015-03-19 06:18:30

标签: haskell types type-level-computation

使用TypeOperators玩弄我已尝试实施$.,这样我就可以删除任何括号的程序(对任何漂亮的Lispers都没有冒犯)。在这样做的过程中,我以同形方式复制了这些定义。首先,我尝试仅使用$因为您不需要.强大的力量。

{-# LANGUAGE TypeOperators #-}
type f $ a = f a

f :: Int -> IO $ Either String Int
f n = undefined

大。编译,我很满意。

{-# LANGUAGE TypeOperators #-}
type f $ a = f a

f :: Int -> IO $ Maybe $ Either String Int
f n = undefined

这应该可行吗?

TyCo.hs:4:18:
    Expecting one more argument to ‘Maybe’
    The second argument of ‘$’ should have kind ‘*’,
      but ‘Maybe’ has kind ‘* -> *’
    In the type signature for ‘f’:
      f :: Int -> (IO $ Maybe) $ Either String Int

显然不是。

{-# LANGUAGE TypeOperators #-}
type f $ a = f a
type (f * g) a = f (g a)

f :: Int -> IO * Maybe $ Either String Int
f n = undefined

怀着盲目的希望,我试试。

TyCo.hs:5:6:
    Type synonym ‘*’ should have 3 arguments, but has been given 2
    In the type signature for ‘f’:
      f :: Int -> (IO * Maybe) $ Either String In

在我无知的昏迷中,我提出了一个问题:WHY不起作用吗?

1 个答案:

答案 0 :(得分:1)

第一个问题与$的固定性有关,您可以通过注意放置括号的位置来查看错误消息中的符号。 (IO $ Maybe)是部分应用的类型同义词,导致错误。您不能部分应用类型同义词,因为它需要比较它们,这等同于比较函数。

LiberalTypeSynonyms只是在进行类型检查之前使GHC解包类型同义词,即(IO * Maybe) $ Either String Int变为(IO (Maybe (Either String Int)))然后进行类型检查。这意味着*不再部分应用,程序将编译。