组合类型构造函数,如函数

Ale*_*lec 8 haskell

我最近遇到过一种情况,我希望能够在实例声明中组合类型构造函数.我本来希望这样做:

instance (SomeClass t, SomeClass t') => SomeClass (t . t') where
Run Code Online (Sandbox Code Playgroud)

(t . t')定义成(t . t') a = t (t' a)(所以tt'有样* -> *,我们可以部分应用型构造,如函数,那么什么是我们不能撰写他们的原因是什么?此外,有没有可能是什么,我想实现一个解决方法吗?也许平等约束?

(我知道Control.Compose存在,但它只是创建一个newtype包装器 - 我想要一个类型的同义词).

chi*_*chi 10

(我知道它Control.Compose存在,但它只是创建一个 newtype包装器 - 我想要一个类型的同义词).

这在Haskell中是不允许的.必须完全应用类型同义词:您不能Compose t t'只写Compose t t' a.

允许部分应用的类型同义词会导致类型级别的lambdas,这使得类型推断不可判定,因此在Haskell中缺乏对它的支持.


例如,(启用所有相关的GHC扩展)

type Compose t t' a = t (t' a)
data Proxy (k :: * -> *) = Proxy

pr :: Proxy (Compose [] [])
pr = Proxy
Run Code Online (Sandbox Code Playgroud)

结果是:

 Type synonym ‘Compose’ should have 3 arguments, but has been given 2
    In the type signature for ‘pr’: pr :: Proxy (Compose [] [])
Run Code Online (Sandbox Code Playgroud)

同样的,

class C k where f :: k Int -> Int
instance C (Compose [] []) where f _ = 6
Run Code Online (Sandbox Code Playgroud)

收益率:

Type synonym ‘Compose’ should have 3 arguments, but has been given 2
    In the instance declaration for ‘C (Compose [] [])’
Run Code Online (Sandbox Code Playgroud)

以下允许使用类型同义词部分应用程序的示例,而不是(启用LiberalTypeSynonyms):

type T k = k Int
type S = T (Compose [] [])

bar :: S -> S
bar = map (map succ)
Run Code Online (Sandbox Code Playgroud)

但请注意,这仅仅是因为在同义词扩展后我们得到一个完全应用的类型[] ([] Int)(即[[Int]]).粗略地说,这个功能不允许做任何人没有它可以做的事情,手动扩展同义词.

  • 的确,虽然`-XLiberalTypeSynonyms`在某些情况下允许部分应用类型同义词.但是,不是在这种情况下. (3认同)