Haskell map是如何在内部实现的?
好的,我想实现我的自定义映射,它接收一个复制因子和一个目标列表 输入:Haskell map是如何在内部实现的?,haskell,Haskell,好的,我想实现我的自定义映射,它接收一个复制因子和一个目标列表 输入:Int->[Int] 输出:[[Int]] 例如:2[1,2]------>[1,1],[2,2]] f[1,2,3]->map->[f(1),f(2),f(3)] 当map转到列表的下一个元素时,f(1)应该发生什么?我应该如何用f(1)替换1 这是我最初的解决方案,但它确实复制了最初的列表,而不是每个元素 replicate::Int->[Int]->[[Int]] replicate 1 x=x replic
Int->[Int]
输出:
[[Int]]
例如:
2[1,2]------>[1,1],[2,2]]
f[1,2,3]
->map->[f(1),f(2),f(3)]
当map转到列表的下一个元素时,f(1)应该发生什么?我应该如何用f(1)替换1
这是我最初的解决方案,但它确实复制了最初的列表,而不是每个元素
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
有两个问题会阻止您的代码编译:
null
函数的类型为[a0]->Bool
,但您正在应用它
在列表的元素上,因此您希望它是Int->Bool
fx
不应该被推到输入的尾部,而是
应推送到函数递归调用的结果中:
fx:(mymap fxs)
而不是fx:xs
mymap :: (Int -> [Int]) -> [Int]-> [[Int]]
mymap f (x:xs) = if null xs then [] else f x : (mymap f xs)
顺便说一句,标准库通过模式匹配提供了可读性强(而且是多态性的):
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
有两个问题会阻止您的代码编译:
null
函数的类型为[a0]->Bool
,但您正在应用它
在列表的元素上,因此您希望它是Int->Bool
fx
不应该被推到输入的尾部,而是
应推送到函数递归调用的结果中:
fx:(mymap fxs)
而不是fx:xs
mymap :: (Int -> [Int]) -> [Int]-> [[Int]]
mymap f (x:xs) = if null xs then [] else f x : (mymap f xs)
顺便说一句,标准库通过模式匹配提供了可读性强(而且是多态性的):
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
接收复制因子和目标列表的自定义映射
我不太清楚你要什么
mymap
是否接收复制因子,或者f
例如:2[1,2]------>[1,1],[2,2]]
如果希望mymap 2[1,2]
给出[[1,1],[2,2]]
,则:
mymap :: Int -> [a] -> [[a]]
mymap = map . replicate
但是,
这个函数与内置的map:(a->b)->[a]->[b]
和a
作为Int
和b
作为[Int]
有什么不同?这里,mymap
本身没有任何Int
参数,因此您必须说明f
的参数是复制因子;但是如果f23==[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
或者您可以使用列表理解而不是映射
:
mymap :: Int -> [a] -> [[a]]
mymap n xs = [ replicate n x | x <- xs ]
mymap::Int->[a]->[[a]]
mymap nxs=[复制nx | x
接收复制因子和目标列表的自定义映射
我不太清楚你要什么
mymap
是否接收复制因子,或者f
例如:2[1,2]------>[1,1],[2,2]]
如果希望mymap 2[1,2]
给出[[1,1],[2,2]]
,则:
mymap :: Int -> [a] -> [[a]]
mymap = map . replicate
但是,
这个函数与内置的map:(a->b)->[a]->[b]
和a
作为Int
和b
作为[Int]有何不同
?在这里,mymap
本身没有任何Int
参数,因此您的意思是f
的参数是复制因子;但是如果f23==[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
或者您可以使用列表理解而不是映射
:
mymap :: Int -> [a] -> [[a]]
mymap n xs = [ replicate n x | x <- xs ]
mymap::Int->[a]->[[a]]
mymap n xs=[replicate n x | x我认为您可以实现map而不必在列表上设置限制。我认为您可以以某种方式用其他内容替换列表中的所有元素。不,在后台map
肯定需要使用:
模式构造函数解构其输入,并使用:
值con重构其结果structor(operator)。一旦你有了足够多的有用的高阶函数,比如map
和replicate
,你就可以利用它们来避免写显式的consing,但它们仍然是隐藏的。这就是我想要的圣杯解释:D谢谢你,先生。我想你可以[(插入这里),(插入这里),(插入此处)]您只能对固定长度的列表执行此操作。@Bercoviciarian甚至[foo,bar,baz]
对于调用:
;特别是foo:bar:baz:[]
。我认为您可以实现map,而不必在列表上设置约束。我认为您可以以某种方式用其他内容替换列表中的所有元素。不,在后台map
肯定需要使用:
模式构造函数解构其输入,并使用:
值构造函数重构其结果(操作符)。一旦你有了足够多有用的高阶函数,比如map
和replicate
,你就可以利用它们来避免编写显式的consing,但它们仍然会出现在引擎盖下。这就是我想要的圣杯解释:D谢谢你,先生。我想你可以[(插入这里),(插入这里),(插入这里)]您只能对固定长度的列表执行此操作。@Bercovicadrian甚至[foo,bar,baz]
对于调用:
;具体来说,foo:bar:baz:[]
。注意:“输入:Int->[Int]
,输出:[[Int]]
”表明函数应该具有签名(Int->[Int])[[Int]]
,它与Int->[Int]->[[Int]]]
非常不同。后者实际上被解析为