地图如何在内部实施?

时间:2018-04-03 07:54:09

标签: haskell

好的,所以我想实现我的自定义地图,它接收复制因子和目标列表。

输入:Int -> [Int]
输出:[[Int]]
例如:2 [1,2] -----> [[1,1],[2,2]]

f [1,2,3] - >地图 - > [f(1),f(2),f(3)]

当map转到列表的下一个元素时,f(1)会发生什么?我应该如何用f(1)替换1?

P.S:这是我的初始解决方案,但它确实复制了初始列表,而不是每个元素。

replicate::Int->[Int]->[[Int]]
replicate 1 x=x
replicate factor (x:xs)= go factor [] (x:xs) where
                         go factor ls (x:xs) =go factor (repl factor x):ls xs 
                         repl 1 nr=nr
                         repl times nr=nr:repl (times-1) nr

2 个答案:

答案 0 :(得分:5)

有两个问题阻止您的代码编译:

  1. null函数的类型为[a0] -> Bool,但您正在应用它     在列表的元素上,因此您期望它是Int -> Bool

  2. 结果f x不应该被推入输入的尾部,它 应该被推入函数的递归调用的结果: f x: (mymap f xs)代替f x: xs

  3. 因此,以下代码应该有效:

    mymap :: (Int -> [Int]) -> [Int]-> [[Int]]
    mymap f (x:xs) = if null xs then [] else f x : (mymap f xs)
    

    顺便说一句,标准库使用模式匹配提供了更多可读(也是多态)implementation

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

答案 1 :(得分:2)

  

接收复制因子和目标列表的自定义地图

我有点不清楚你要求的是什么。

mymap是否收到复制因子,或f

  

例如:2 [1,2] -----> [[1,1],[2,2]]

如果您希望mymap 2 [1,2]提供[[1,1],[2,2]],那么:

mymap :: Int -> [a] -> [[a]]
mymap = map . replicate

然而,

mymap :: (Int -> [Int]) -> [Int] -> [[Int]]

此功能与内置map :: (a -> b) -> [a] -> [b]的{​​{1}}与aInt的{​​{1}}有何不同?在这里,b本身没有任何[Int]参数,因此您必须表示mymap的参数是复制因子;但如果Int,则f f 2 3 == [3,3],您可以使用上述解决方案。

如果您愿意,可以使用自己的递归定义来编写:

f

或者您可以使用列表理解而不是replicate

mymap :: Int -> [a] -> [[a]]
mymap _ [] = []
mymap n (x:xs) = myreplicate n x : mymap n xs

myreplicate :: Int -> a -> [a]
myreplicate 0 _ = []
myreplicate n x = x : myreplicate (n-1) x

我可能会为map或类似的事情致电mymap :: Int -> [a] -> [[a]] mymap n xs = [ replicate n x | x <- xs ]