haskell - 函数组合中的类型推导

标签 haskell type-parameter

你好,我有一个带有类型参数的类型:

data A=A1| A2 deriving (Show)
data B=B1| B2 deriving(Show)
data C a=C{var::a,var2::Int}

getters=[show . var,show .var2]

我在 show 的 getters 中收到以下错误。变量:

Ambiguous type variable `a0' arising from a use of `show'
      prevents the constraint `(Show a0)' from being solved.
      Relevant bindings include
        getters:: [Worker a0 -> String]

我是否必须明确声明类型,例如:show. (var::B)。我不太明白这个错误,因为 AB 类型都在实现 Show

最佳答案

编辑:更新如下以回答您的后续问题。

为了回答您原来的问题,这只是类型检查器需要一点帮助的情况。您可以通过为 getters 添加显式签名来对代码进行类型检查,如 @WillemVanOnsem 建议的那样:

data A = A1 | A2 deriving (Show)
data B = B1 | B2 deriving (Show)
data C a = C { var :: a, var2 :: Int }

getters :: (Show a) => [C a -> String]
getters = [show . var, show . var2]

或者,正如 @DanielWagner 指出的那样,打开 NoMonomorphismRestriction GHC 扩展。完成其中任一操作后,以下工作正常:

> map ($ C A1 10) getters
["A1","10"]
> map ($ C B2 10) getters
["B2","10"]
> 

如果您对方法的评论是针对 Willem,则此签名不会使 getters 成为“方法”。它仍然是一个 [C a -> String] 类型的多态表达式(对于任何带有 Show a 约束的 a 类型)。

更新:根据您的评论,您认为想要定义一种数据类型,并对其一个或多个字段的类型进行约束。 (你实际上并不想这样做——你只是认为你这样做——但我有什么资格阻止你呢?)

因此,要执行此操作,您需要启用 DatatypeContexts 扩展并写入:

{-# LANGUAGE DatatypeContexts #-}

class Mytypeclass a where
  whatever :: a -> String

data Mytypeclass a => MyType a = M { var :: a, var2 :: a }

编译器将生成一条警告,表明此扩展已被弃用,因为它被广泛认为是一个错误功能并已从语言中删除。

现在,您可以定义:

getters = [whatever . var, whatever . var2]

这会给你一个错误,尽管错误消息与以前不同,之后你可以添加签名:

getters :: (Mytypeclass a) => [MyType a -> String]
getters = [whatever . var, whatever . var2]

或者启用 NoMonomorphismRestriction 扩展以便使其能够编译,就像以前一样。

关于haskell - 函数组合中的类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51360842/

相关文章:

c# - 在 C# 中将泛型作为泛型类型参数传递

haskell - 在 Haskell 中程序生成大量值列表——最惯用的方法?内存管理?

Haskell - 类型类扩展

haskell - 如何在幻像类型的模式匹配中指定类型参数

java - 无法编译实现没有类型参数的接口(interface)的类

java - 如何验证(泛型(generic argument))?

java - 在 Java 中,类型变量的边界只能出现在类型变量声明中,对吗?

haskell 错误: Couldn't match type 'a' with 'b'

Haskell 无法匹配类型

haskell - 找到一个定理的计算解释