带参数的Haskell自定义数据类型

时间:2015-03-20 11:34:05

标签: haskell

我有一个自定义数据类型如下:

 data MyType a = Nothing
             | One a

我们的想法是拥有一个返回数据类型的函数。例如,

func (One Char)应该返回Char - 返回数据类型

我尝试按照以下方式实施func

func :: MyType a -> a
func (One a) = a
-- don't worry about Nothing for now

编译的代码但是当我尝试运行func (One Char)时,它给出了一个错误:Not in scope: data constructor ‘Char’

发生了什么事?

3 个答案:

答案 0 :(得分:2)

尝试func (One "Hello")它会起作用。

原因是Haskell认为你试图给它一个数据构造函数因为你写了一个大写的Char所以只是给它一些真正的价值;)

BTW:如果你真的想要提供类型 Char:在Haskell中通常不可能,因为你需要一个依赖类型的上限(参见{{ 3}}例如)。

答案 1 :(得分:1)

这并不是真的如何运作。 Char是一种类型,因此我们可以编写

func :: MyType Char -> Char

意思是我们期待"某事" MyType成为Char。

检查参数的类型可能在Java等方面有效,但不是函数式编程的工作方式。

答案 2 :(得分:0)

我不认为你真的希望通过你目前对Haskell的理解(这对我来说很棒,而且我&#39)很有可能。已经有一段时间了,但如果你真的这么做,你实际上可以得到一些非常接近的东西。

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-} --might as well

-- I renamed Nothing to None to avoid conflicting with Maybe.
-- Since we're using DataKinds, this creates not only a type
-- constructor MyType and data constructors None and One,
-- but also a *kind* MyType and *type* constructors None and
-- One.
data MyType a = None | One a

-- We can't make a *function*, func, to take One Char and
-- produce Char, but we can make a *type function* (called
-- a type family) to do that (although I don't really know
-- why you'd want this particular one.
type family Func (a :: MyType k) :: k
type instance Func (One a) = a

现在,如果我们写

Prelude> '3' :: Func (One Char)

GHCi非常满意。事实上,我们可以使这种类型的功能更加通用:

type family Func2 (a :: g) :: k where
  Func2 (f a) = a

现在我们可以写

'c' :: Func2 (One Char)

但我们也可以写

'c' :: Func2 (Maybe Char)

甚至

'c' :: Func2 (Either Char)
'c' :: Func2 ((Either Int) Char)

但如果您认为有什么事情发生,

'c' :: Func2 (Maybe Int)

'c' :: Func2 Char

会出错。