Haskell 类型运算符的顺序和种类要求

Haskell 类型运算符的顺序和种类要求,haskell,types,type-level-computation,Haskell,Types,Type Level Computation,玩弄类型操作符我已经尝试实现了$和,这样我就可以去掉程序中的任何括号(对任何漂亮的Lisper都没有冒犯)。在这样做的过程中,我同构地复制了这些定义。首先,我尝试只使用$,因为您不需要的强大功能 {-# LANGUAGE TypeOperators #-} type f $ a = f a f :: Int -> IO $ Either String Int f n = undefined 太好了。这是编译,我很满意 {-# LANGUAGE TypeOperators #-} typ

玩弄
类型操作符
我已经尝试实现了
$
,这样我就可以去掉程序中的任何括号(对任何漂亮的Lisper都没有冒犯)。在这样做的过程中,我同构地复制了这些定义。首先,我尝试只使用
$
,因为您不需要
的强大功能

{-# 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

在我无知的昏迷中,我提出了一个问题:
为什么它不起作用?

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


LiberalTypeSynonyms
在进行类型检查之前,只需将GHC展开类型同义词,即,
(IO*Maybe)$任一字符串Int
变为
(IO(Maybe)(任一字符串Int))
,然后进行类型检查。这意味着
*
不再部分应用,程序将编译。

对于第一个示例,看起来
$
的关联性是错误的。我假设值级别的
$
和类型级别的
$
被视为不同的标识符,我们没有为后者声明优先级或关联性。我不知道怎么做,或者有没有办法。至少玩一下
infixr
,如果您希望这些快捷方式通常有用,那么还应该启用
PolyKinds
和/或
LiberalTypeSynonyms
。@luqui的评论都是正确的。您可以使用
infixr 0$
修复第一个版本,使用
LiberalTypeSynonyms
修复第二个版本。但是请注意,
$
不足以去除所有括号。多亏了你们,我现在已经解决了这两个问题。别忘了发布答案,这样你就可以申请电子积分并对系统进行测试。