haskell函数给定类型签名处理列表

haskell函数给定类型签名处理列表,haskell,Haskell,给定这种类型的签名,mapNew应该是什么样的函数 我知道退货类型是list 这看起来很像一个家庭作业问题。如果是的话,我强烈建议你试着自己回答这个问题。话虽如此,我将带您了解我将如何制定这个问题的答案,并希望能让您了解应该如何处理此类问题 我们知道mapNew的类型是a->(a->b->c)->[b]->[c]。这看起来很像现有的Prelude函数map::(a->b)->[a]->[b]。所以我们可能想用map来写答案 mapNew :: a -> (a -> b -> c

给定这种类型的签名,
mapNew
应该是什么样的函数


我知道退货类型是list

这看起来很像一个家庭作业问题。如果是的话,我强烈建议你试着自己回答这个问题。话虽如此,我将带您了解我将如何制定这个问题的答案,并希望能让您了解应该如何处理此类问题

我们知道
mapNew
的类型是
a->(a->b->c)->[b]->[c]
。这看起来很像现有的Prelude函数
map::(a->b)->[a]->[b]
。所以我们可能想用
map
来写答案

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
    where fa :: b -> c
          fa = f a
我们总是从写出函数及其参数开始,这样我们就可以看到需要处理的部分。知道我们只有一个
a
,并且需要始终将它传递给
f
对于
bs
中的每个元素
b
,我们可以为该部分应用程序添加一个
where
子句:

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
有鉴于此,我们现在可以用
map
来编写答案

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
    where fa :: b -> c
          fa = f a
大多数haskell程序员会将此定义简化为:

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = map fa bs
    where fa :: b -> c
          fa = f a
因为
(fa)
正是部分应用的函数
fa
。此外,我们可以将此表达式简化为:

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = map (f a) bs
这个答案的关键在于“知道我们只有一个
a
,并且需要始终为
bs
中的每个元素
b
将其传递给
f
”。我怎么知道的


由于参数多态性,我们无法检查
a
类型的任何值。这意味着我们可以使用的
a
类型的唯一值是传递给
mapNew
的值。此外,由于
f
获取一个
b
并生成一个
c
,我们知道必须首先从提供的列表中获取一个
b
,以便对其应用
f
。这正是
map
所做的,通过将
f
部分应用于
a
我们得到了要传递给
map
的第一个参数,这看起来很像一个家庭作业问题。如果是的话,我强烈建议你试着自己回答这个问题。话虽如此,我将带您了解我将如何制定这个问题的答案,并希望能让您了解应该如何处理此类问题

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
    where fa :: b -> c
          fa = f a
我们知道
mapNew
的类型是
a->(a->b->c)->[b]->[c]
。这看起来很像现有的Prelude函数
map::(a->b)->[a]->[b]
。所以我们可能想用
map
来写答案

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
    where fa :: b -> c
          fa = f a
我们总是从写出函数及其参数开始,这样我们就可以看到需要处理的部分。知道我们只有一个
a
,并且需要始终将它传递给
f
对于
bs
中的每个元素
b
,我们可以为该部分应用程序添加一个
where
子句:

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
有鉴于此,我们现在可以用
map
来编写答案

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
    where fa :: b -> c
          fa = f a
大多数haskell程序员会将此定义简化为:

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = map fa bs
    where fa :: b -> c
          fa = f a
因为
(fa)
正是部分应用的函数
fa
。此外,我们可以将此表达式简化为:

mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = map (f a) bs
这个答案的关键在于“知道我们只有一个
a
,并且需要始终为
bs
中的每个元素
b
将其传递给
f
”。我怎么知道的


由于参数多态性,我们无法检查
a
类型的任何值。这意味着我们可以使用的
a
类型的唯一值是传递给
mapNew
的值。此外,由于
f
获取一个
b
并生成一个
c
,我们知道必须首先从提供的列表中获取一个
b
,以便对其应用
f
。这正是
map
所做的,通过将
f
部分应用于
a
我们得到了要传递给
map
的第一个参数,这是一个将相同的
a
和每个from
[b]
应用于作为第二个参数传递的函数,并生成
[c]
。因此,实现可能只是
a->(a->b->c)->b->c
[b]
上的
映射,它是一个函数,将相同的
a
和每个from
[b]
应用于作为第二个参数传递的函数,并生成
[c]
。因此,实现可能只是
a->(a->b->c)->b->c的
映射
[b]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew :: a -> (a -> b -> c) -> [b] -> [c]
mapNew a f bs = ...
    where fa :: b -> c
          fa = f a