我有一个类型Foo a,想要一个EnumFoo a需要的类型instance Enum (Foo a).你怎么声明这种类型?
假设我们这样声明Foo:
type Foo a = Maybe a
Run Code Online (Sandbox Code Playgroud)
可以有Foo Int,有Foo String什么.
现在我声明一个Enumon 的实例Foo Int:
instance Enum (Foo Int) where
...
Run Code Online (Sandbox Code Playgroud)
可能还有其他Foo一些具有这样的实例Enum.我们称之为那些类型EnumFoo a.你是怎么表达的?
这不起作用,但我想做的是:
type (Enum (Foo a)) => EnumFoo a = Foo a
Run Code Online (Sandbox Code Playgroud)
我不确定它叫什么,所以标题应该毫无意义.
正如bheklilr 所说,听起来你想要的是一个GADT:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
module Foo where
data Foo a = Foo (Maybe a)
data EnumFoo a where
EnumFoo :: Enum (Foo a) => Foo a -> EnumFoo a
Run Code Online (Sandbox Code Playgroud)
制作EnumFoo a(除了undefined)之外的唯一方法是应用EnumFoo构造函数,它构造了一个Enum (Foo a)上下文.然后你可以写出类似的东西
blah :: EnumFoo a -> [EnumFoo a]
blah (EnumFoo foo) = map EnumFoo [toEnum 1 .. foo]
Run Code Online (Sandbox Code Playgroud)
请注意,您需要FlexibleContexts扩展名,因为标准Haskell不允许上下文Enum (Foo a); 它只允许简单的事情,如Enum Foo或Enum a.
bheklilr还提到了一个较旧的声明表,在标准data声明中加上了背景.虽然这种形式是标准的Haskell(它在Haskell 98和Haskell 2010报告中),但它被广泛认为是错误的,GHC甚至不允许没有LANGUAGE编译指示.问题在于虽然它限制了允许的类型变量,但它不允许您使用这些约束.
| 归档时间: |
|
| 查看次数: |
77 次 |
| 最近记录: |