有“类型级组合器”吗?他们将来会存在吗?

时间:2011-11-23 19:49:35

标签: haskell types combinators type-level-computation

在我看来,使用haskell非常好用的大部分内容都是(.)flip$ <*>等组合器。感觉就像我能在需要时创建新语法。

前段时间我正在做一些事情,如果我可以“翻转”,那将是非常方便的。一个类型构造函数。假设我有一些类型构造函数:

m  :: * -> * -> * 

并且我有一个类MyClass,它需要一个带有类型* -> *的类型构造函数的类型。当然,我会选择以这样的方式对类型进行编码:

instance MyClass (m a) 

但是假设我无法更改该代码,并假设真正符合MyClass的内容就像是

type w b = m b a 

instance MyClass w where 
    ...

然后我必须激活XTypeSynonymInstances。有没有办法创建一个&#34;类型级别的组合器&#34; Flip我可以这样做:

instance MyClass (Flip m a)  where 
   ...

??或者我们在haskell中使用的常见运算符的其他类型级概括?这甚至是有用的还是我只是漫无目的?

编辑:

我可以这样做:

newtype Flip m a b = Flip (m b a)

newtype Dot m w a  = Dot m (w a)

...

但是我必须使用数据构造函数FlipDot,...来进行模式匹配等等。值得吗?

3 个答案:

答案 0 :(得分:11)

你的问题很有道理,但答案是:不,目前不可能。

问题在于(在GHC Haskell的类型系统中)你不能在类型级别拥有lambdas。对于你可能尝试的任何东西看起来它可以模拟或实现类型级别lambda的效果,你会发现它不起作用。 (我知道,因为我做了。)

你可以做的是声明你的翻转新类型,然后编写你想要的类的实例,痛苦地包装和解包(顺便说一句:使用记录语法),然后类的客户端可以使用类型签名中的新类型,不必担心细节。

我不是一个类型理论家,我不知道为什么我们不能拥有类型级别的lambdas的细节。我认为这与类型推断变得不可能有关,但我再也不知道了。

答案 1 :(得分:3)

您可以执行以下操作,但我认为它实际上并不十分有用,因为您仍然无法真正部分应用它:

{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
module Main where

class TFlip a where
    type FlipT a

instance TFlip (f a b) where
    type FlipT (f a b) = f b a 

-- *Main> :t (undefined :: FlipT (Either String Int))
-- (undefined :: FlipT (Either String Int)) :: Either Int [Char]

另见前面的讨论:Lambda for type expressions in Haskell?

答案 2 :(得分:2)

我在这里写答案只是为了澄清事情并讲述过去几年的成就。 Haskell 中有很多功能,现在您可以在类型中编写一些运算符。使用$,你可以这样写:

foo :: Int -> Either String $ Maybe $ Maybe Int

避免使用括号而不是旧的

foo :: Int -> Either String (Maybe (Maybe Int))