17

在我看来,使haskell 真正好用的大部分是组合符,例如,(.)等。感觉就像我可以在需要时创建新语法一样。flip$ <*>

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

m  :: * -> * -> * 

并且我有一个类MyClass需要一个带有 kind 类型构造函数的类型* -> *。自然,我会选择以我可以做到的方式对类型进行编码:

instance MyClass (m a) 

但是假设我无法更改该代码,并假设真正适合MyClass的内容类似于

type w b = m b a 

instance MyClass w where 
    ...

然后我必须激活XTypeSynonymInstances. 有没有办法创建一个“类型级组合器” 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)

...

但后来我不得不使用数据构造函数Flip, Dot, ... 来进行模式匹配等。值得吗?

4

3 回答 3

11

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

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

你可以做的是声明你的 Flip 新类型,然后为它们编写你想要的类的实例,痛苦地进行包装和展开(顺便说一句:使用记录语法),然后类的客户可以使用新类型类型签名,而不必担心细节。

我不是类型理论家,我不知道为什么我们不能拥有类型级 lambdas 的细节。我认为这与类型推断变得不可能有关,但同样,我真的不知道。

于 2011-11-23T20:53:24.657 回答
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 用于 Haskell 中的类型表达式?

于 2011-11-23T21:13:07.613 回答
2

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

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

避免括号而不是好旧的

foo :: Int -> Either String (Maybe (Maybe Int))
于 2017-03-27T14:46:03.223 回答