【问题标题】:Having trouble understanding Haskell's type system无法理解 Haskell 的类型系统
【发布时间】:2012-08-21 01:52:25
【问题描述】:

我目前正在尝试做20 Intermediate Haskell Exercises。我能够完成第 3 次练习(但这是因为 furry == fmapLearn You a Haskell 已经有了这些实现)。我目前被困在这样的实例上:

instance Fluffy (EitherLeft t) where                                        
  furry = error "todo"

我真的不明白该怎么做。在 Learn You Haskell 中,他们有一个名为 Pairnewtype 变量,它接收一个元组。然后他们可以像这样进行模式匹配:

  fmap f (Pair (x,y)) = Pair (f x, y)

我在想也许你可以在我的情况下做类似的事情:

  furry f (EitherLeft (Either a b)) = EitherLeft (Either (f a) b)

但是,这不起作用:

Not in scope: data constructor `Either'

我在想也许我会import Data.Either,因为他可能有一些我没有的进口东西。但这没关系。

我也试图让这个工作:

  furry f (EitherLeft a b) = error "todo"

但这也不起作用:

Constructor `EitherLeft' should have 1 argument, but has been given 2

我也无法让它工作:

  furry f (Right x) = (Right f x)
  furry f (Left x) = Left x

哪个给出了错误:

Couldn't match expected type `EitherLeft t a'
            with actual type `Either t0 t1'

我只能得到:

  furry f (EitherLeft t) = error "todo"

工作。但我不知道如何处理t

我不一定想要答案。我只需要一个关于该做什么的提示,因为我正在阅读并且我可以理解这些示例,但我无法真正开始自己编写这些东西。

感谢 Dan,这就是我想出的解决方案:

instance Fluffy (EitherLeft t) where                     
  furry f (EitherLeft (Left x)) = EitherLeft $ Left  (f x)                   
  furry f (EitherLeft (Right x)) = EitherLeft $ Right x

【问题讨论】:

  • 一开始很难区分类型名称和构造函数名称,所以这里有一个规则:在类型定义data Foo = Foo 中,left 的大写名称的= only 曾经出现在类型签名和类实例声明中。 = 右侧的大写字母只出现在代码
  • 我认为将您的解决方案放在问题中并不是一个好习惯。这让未来的读者不清楚您坚持什么,以及您已经解决了什么问题。

标签: haskell types constructor overloading algebraic-data-types


【解决方案1】:

您遇到的问题是 Either 数据类型没有名为 Either 的数据构造函数,基本上 Either 类型看起来像这样

data Either a b = Left a
                | Right b

所以一个值可以有 Either a b 类型,但没有像 Either "one" 1 或类似的值,而是 Left "one"Right 1

所以在EitherLeft 的情况下,类似地,它的值看起来像EitherLeft (Left a)EitherLeft (Right b),因此需要进行模式匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    相关资源
    最近更新 更多