Haskell: `where` 中的类型声明

标签 haskell types

我有一个函数示例,其中我无法在 where 子句中编写类型。 replace 是一个函数,它将给定列表中的所有 X 替换为 Y。

replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y xs = map helper xs
  where
    helper :: (Eq a) => a -> a
    helper = (\el -> if el == x then y else el)

当我尝试编译此函数时,出现错误:

ProblemsArithmetics.hs:156:31:
Could not deduce (a ~ a1)
from the context (Eq a)
  bound by the type signature for
             replace :: Eq a => a -> a -> [a] -> [a]
  at ProblemsArithmetics.hs:152:12-41
or from (Eq a1)
  bound by the type signature for helper :: Eq a1 => a1 -> a1
  at ProblemsArithmetics.hs:155:15-30
  ‘a’ is a rigid type variable bound by
      the type signature for replace :: Eq a => a -> a -> [a] -> [a]
      at ProblemsArithmetics.hs:152:12
  ‘a1’ is a rigid type variable bound by
       the type signature for helper :: Eq a1 => a1 -> a1
       at ProblemsArithmetics.hs:155:15
Relevant bindings include
  el :: a1 (bound at ProblemsArithmetics.hs:156:16)
  helper :: a1 -> a1 (bound at ProblemsArithmetics.hs:156:5)
  xs :: [a] (bound at ProblemsArithmetics.hs:153:13)
  y :: a (bound at ProblemsArithmetics.hs:153:11)
  x :: a (bound at ProblemsArithmetics.hs:153:9)
  replace :: a -> a -> [a] -> [a]
    (bound at ProblemsArithmetics.hs:153:1)
In the second argument of ‘(==)’, namely ‘x’
In the expression: el == x

同时,如果我省略

helper :: (Eq a) => a -> a

代码编译良好。

虽然我理解其背后的逻辑(replace类型声明中的ahelper类型声明中的a是不同的 a ),并且至少有 2 种解决方法(省略类型声明或将 xy 作为参数传递给 helper 函数),我的问题是:

有什么方法可以告诉编译器我在两个类型声明中指的是相同的类型吗?

最佳答案

如果启用ScopedTypeVariables并使用 forall 引入一个类型变量,然后它在内部作用域中变得可见。

{-# LANGUAGE ScopedTypeVariables #-}

replace :: forall a. (Eq a) => a -> a -> [a] -> [a]
replace x y xs = map helper xs
  where
    helper :: a -> a
    helper = (\el -> if el == x then y else el)

关于Haskell: `where` 中的类型声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29274751/

相关文章:

Haskell 线性代数库与同类类具有多态性 *

function - 运算符的 Haskell 类型优先级高于函数

parsing - 如何解析文本并提取整数

PHP 智能 || (OR) 运算符就像 JavaScript 中一样

c# - 如何将 double 转换为 int?

scala - 在 scala 中将 Int 添加到字符串

haskell - 如何在不执行括号的情况下定义简单的 RIO LogFunc

haskell - 在使用类型系列限制 GADT 时摆脱 "non-exhaustive patten matches"警告

.net - 如何检索 .net 中泛型 IEnumerable 中使用的泛型类型?

c - 如何在 C 中检查变量是否属于某种类型(比较两种类型)?