【问题标题】:How to fix "Couldn't match expected type" error in Haskell?如何修复 Haskell 中的“无法匹配预期类型”错误?
【发布时间】:2019-06-28 14:46:27
【问题描述】:

我是 Haskell 的新手,现在正在学习类型课程。我创建了一个简单的类型类,但不幸的是我无法修复

无法匹配预期类型

-- So a can be Int, Float etc
data MyShape a = Circle a -- etc like | Rectangle a a 
  deriving(Show)

class Geo a where
  inflate :: Num b => a -> b -> a
  area :: Num b => a -> b

instance Num a => Geo (MyShape a) where
  inflate (Circle r) x = Circle (r * x)
  area (Circle r) = 3 * r * r

它不喜欢膨胀和面积函数。

错误:

• Couldn't match expected type ‘a’ with actual type ‘b’
      ‘b’ is a rigid type variable bound by
        the type signature for:
          inflate :: forall b. Num b => MyShape a -> b -> MyShape a
        at test2.hs:122:3-9
      ‘a’ is a rigid type variable bound by
        the instance declaration
        at test2.hs:121:10-33
    • In the second argument of ‘(*)’, namely ‘x’
      In the first argument of ‘Circle’, namely ‘(r * x)’
      In the expression: Circle (r * x)
    • Relevant bindings include
        x :: b (bound at test2.hs:122:22)
        r :: a (bound at test2.hs:122:19)
        inflate :: MyShape a -> b -> MyShape a (bound at test2.hs:122:3)
    |
122 |   inflate (Circle r) x = Circle (r * x)
    |                                      ^

【问题讨论】:

  • 你能显示 full 错误吗?
  • 无法将预期类型“a”与实际类型“b”匹配“b”是受类型签名约束的刚性类型变量:inflate :: forall b。 Num b => MyShape a -> b -> MyShape a at test2.hs:122:3-9 'a' 是一个刚性类型变量,由 test2.hs:121:10-33 处的实例声明绑定 • 在第二个'(*)' 的参数,即'x' 在'Circle' 的第一个参数中,即'(r * x)' 在表达式中:Circle (r * x)
  • 请把错误写在你上面的帖子里。如您所见,未格式化的版本很难阅读。

标签: haskell


【解决方案1】:

问题在于像 (+) :: Num a => a -> a -> a(*) :: Num a => a -> a -> a 这样的操作要求 操作数 具有相同的 em>类型。不能将IntInteger 加在一起,也不能将FloatDouble 相乘。存在一些像fromIntegral :: (Integral a, Num b) => a -> b 这样的转换,但据我所知,这些转换不能将任意Num 类型转换为任意Num 类型,而且它可能导致不精确。例如,通过将Integer 转换为Float,您可能会“丢失数据”。

例如,您的inflate :: (Geo a, Num b) => a -> b -> a 函数会产生两种不同的类型,即膨胀常量x 的类型和圆圈中值的类型。两者都是Num 类型,但本身不是同一类型。

例如,我们可以将 MyShape 设为 Geo 类的实例,例如:

class Geo a where
  inflate :: Num b => a b -> b -> a b
  area :: Num b => a b -> b

然后定义一个像这样的实例:

instance Geo MyShape where
  inflate (Circle r) x = Circle (r * x)
  area (Circle r) = 3 * r * r

所以这里我们指定MyShape bNum b 有一个inflate :: Num b => MyShape b -> b -> MyShape barea :: Num b => MyShap b -> b 也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    相关资源
    最近更新 更多