Haskell地图的简单版本

时间:2014-07-07 14:25:49

标签: haskell map ghci

我试图以递归方式定义ghci中的地图。到目前为止,我想出的是:

let mymap f (x:xs) = if null xs then [] else f x : map f xs

我现在要做的是简化它并对代码中的列表进行硬编码,即编写一个map函数,该函数将函数作为参数并执行真实映射所做的但仅限于具体列表,例如[1,2,3,4,5]。 这样的事情可能吗?

1 个答案:

答案 0 :(得分:6)

首先,你的地图功能并不完全正确。如果我要输入mymap (+1) [1],我希望得到[2],但我会得到[]。如果我尝试mymap (+1) [],我的程序会因模式匹配失败而崩溃,因为您尚未定义该情况。相反,请考虑将mymap定义为

mymap :: (a -> b) -> [a] -> [b]
mymap f [] = []
mymap f (x:xs) = f x : mymap f xs

如果你想用if语句内联,那么你必须做

mymap f xs = if null xs then [] else f (head xs) : mymap f (tail xs)

这些基本上是相同的,但在我看来,第一个更容易阅读。


如果您想使用mymap来定义仅映射到特定列表的函数,您可以非常轻松地执行此操作

mapOnMyList :: (Int -> b) -> [b]
mapOnMyList f = mymap f [1, 2, 3, 4, 5]

或以无点形式

mapOnMyList = (`mymap` [1, 2, 3, 4, 5])

使用mymap作为中缀运算符。这相当于flip mymap [1, 2, 3, 4, 5],但通常首选运算符表单,因为flip不一定可以自由执行。


您也可以使用列表推导来执行此操作:

mymap f xs = [f x | x <- xs]

或者,如果您想对列表进行硬编码

mapOnMyList f = [f x | x <- [1, 2, 3, 4, 5]]