【问题标题】:Why can't ghci match this type?为什么ghci不能匹配这种类型?
【发布时间】:2017-12-26 10:10:46
【问题描述】:

我正在处理following Haskell book - 正在查看章节Walk the Line

当我在 ghci 中运行以下代码时:

type Birds = Int  
type Pole = (Birds,Birds)  

x -: f = f x

:{
landLeft :: Birds -> Pole -> Maybe Pole
landLeft n (left,right)
    | abs ((left + n) - right) < 4 = Just (left + n, right)
    | otherwise                    = Nothing
:}

:{
landRight :: Birds -> Pole -> Maybe Pole
landRight n (left,right)
    | abs (left - (right + n)) < 4 = Just (left, right + n)
    | otherwise                    = Nothing
:}

--Failure
(0,0) -: landLeft 1 -: landRight 4 
--(0,0) -: landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)  
--(0,2)  

我得到错误:

Prelude> (0,0) -: landLeft 1 -: landRight 4 

<interactive>:17:24: error:
    • Couldn't match type ‘Maybe Pole’ with ‘(Birds, Birds)’
      Expected type: Maybe Pole -> Maybe Pole
        Actual type: Pole -> Maybe Pole
    • In the second argument of ‘(-:)’, namely ‘landRight 4’
      In the expression: (0, 0) -: landLeft 1 -: landRight 4
      In an equation for ‘it’: it = (0, 0) -: landLeft 1 -: landRight 4

我的问题是:为什么ghci不能匹配这种类型?

【问题讨论】:

  • Maybe Pole 不是Pole。您不能将Maybe Pole 传递给需要Pole 的东西。 LYAH 很快就会参与其中。
  • 感谢@AJFarmar - 这很有帮助。您能否就如何解决这个问题进行扩展?
  • LYAH 会告诉你如何做到这一点,但你可以写a :- f = a &gt;&gt;= f 和写Just (0,0) 而不是(0,0)。但再一次,LYAH 很快就会解释这一点。

标签: haskell


【解决方案1】:

-: 一起使用的landLeftlandRight 的变体使用Pole 作为返回类型,而不是Maybe Pole。让我们查看所有类型:

landLeft  1             ::       Pole -> Maybe Pole
landRight 4             ::       Pole -> Maybe Pole 
(-:)                    :: a -> (a    -> b         ) -> b
(0,0)                   :: Pole
(-:) (0,0)              ::      (Pole -> b         ) -> b
(-:) (0,0) (landLeft 1) ::                              Maybe Pole

由于Maybe Pole 不是Pole,我们不能再次将(-:) 用于landRight。 LYAH 展示了如何处理这些函数:您需要一种将a -&gt; Maybe b 函数与Maybe a 一起使用的方法。那是(&gt;&gt;=) 工作:

landLeft 1 (0,0) >>= landRight 4

继续这一章,因为作者会立即解决您的问题:

当我们在不使皮埃尔失去平衡的情况下降落鸟类时,我们会得到一个用Just 包裹的新杆。但是当更多的鸟最终出现在杆子的一侧时,我们会得到一个Nothing。这很酷,但是我们似乎已经失去了将鸟类反复降落在杆子上的能力。我们不能再做landLeft 1 (landRight 1 (0,0)),因为当我们将landRight 1 应用到(0,0) 时,我们得到的不是Pole,而是Maybe PolelandLeft 1 采用 Pole 而不是 Maybe Pole。 [强调我的]

【讨论】:

  • 感谢@Zeta,这很有帮助。你是说书上说错误代码给出了一个有效值 - 这本书包含一个错字吗?
  • @hawkeye 我是说这一章必须按顺序完整阅读。如果您只阅读 sn-ps,您可能会得到损坏的代码。 landLeft两种变体,一种使用Maybe,因此不适合(-:),另一种不使用Maybe,因此适合(-:)。不幸的是,这两个变体名称相同。
猜你喜欢
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
相关资源
最近更新 更多