首页 > 解决方案 > 没有参数的haskell函数中的where子句

问题描述

substitute':: (Eq a)=> a -> a -> [a] -> [a]
substitute' x y = map substituteOne
                  where
                    substituteOne x' | x == x'   = y
                                     | otherwise = x'

所以,这个函数的重点是,它接受两个类型 a 的输入和一个类型 a 的列表,并将列表 [a] 中来自“第一个”a 的所有元素替换为“第二个”a。至少任务描述是这么说的。

我已经实现了一个递归版本,但还需要一个带有 where 子句的函数。

所以这就是它的解决方案。不知何故我有问题:

  1. 第二行中的substituteOne如何在没有任何参数的情况下工作?
  2. 我们在哪里给出一个列表作为输入?或者我们在哪里说明我们如何处理该列表?我的意思是编译和执行它可以工作,但不知何故我看不到它
  3. x' 是什么?它从未在任何地方定义,我们只是以某种方式开始使用它(也许也指问题 1)
  4. map 需要一个函数和一个列表,以便它工作。这里我们有地图功能_。可能指的是 2.,但是替代项 x' 的输出是什么?

如果需要,结果如下所示:

substitute' 5 10 [1, 5, 2, 5, 3, 5]
[1,10,2,10,3,10]

标签: haskellrecursionfunctional-programming

解决方案


(1)在没有任何参数的情况下如何substituteOne在第二行工作?
(2)我们在哪里给出一个列表作为输入?或者我们在哪里说明我们如何处理该列表?我的意思是编译和执行它可以工作,但不知何故我看不到它

参数还在;这是在工作中的柯里化。考虑中缀运算符的部分 (+1),它是偏应用的一种特殊情况。给定一个数字,它会产生一个大一的数字。见证:

λ> :t (+1)
(+1) :: Num a => a -> a

我们可以定义一个函数来通过命名列表来增加列表的所有元素

λ> :t \l -> map (+1) l
\l -> map (+1) l :: Num b => [b] -> [b]

但事实证明这是不必要的,因为currying

λ> :t map (+1)
map (+1) :: Num b => [b] -> [b]

毕竟这是函数式编程。使用 Haskell,我们操作函数就像其他语言操作字符串一样容易。

(3)什么是x'?它从未在任何地方定义,我们只是以某种方式开始使用它(也许也指问题 1)

但是您确实将其定义x'substituteOne!

考虑以下类型map

λ> :t map
map :: (a -> b) -> [a] -> [b]

它的第一个参数是一个参数的函数。为了让您的程序进行类型检查,类型必须对齐。我们可以substituteOne通过添加一个可选的类型注释来强调这一点——但必须更加努力(通过启用作用域类型变量扩展),因为substituteOne它是一个引用外部作用域的内部函数,

substitute':: forall a. Eq a => a -> a -> [a] -> [a]
substitute' x y = map substituteOne
                  where
                    substituteOne :: a -> a
                    substituteOne x' | x == x'   = y
                                     | otherwise = x'

(4) map需要一个函数和一个列表,以便它工作。这里我们有map函数_。可能指的是 2.,但输出会是substituteOne x'什么?

在应用程序点使用未命名的参数,就像您的代码一样,map substituteOne称为无点样式。在您的情况下,有两个不可见的“点”或变量名: 的参数substituteOne和 的列表参数map

你可以对所有事情都很明确,例如

substitute'' :: Eq a => a -> a -> [a] -> [a]
substitute'' x y l = map (\x' -> if x == x' then y else x') l

但相比之下,这要混乱得多。

产生的值substituteOne收集在由 产生的列表中map


推荐阅读