2015-02-15 3 views
0
mapNew :: a -> (a -> b -> c) -> [b] -> [c] 

Данная подпись типа, какая функция должна быть mapNew be?haskell функция данного типа подпись, относящаяся к списку

Я знаю, что тип возврата - это список.

+0

Это функция, которая применяет те же 'a' и каждый из' [b] 'к функции, переданной как 2-й аргумент, и производит' [c] '. Таким образом, реализация может быть просто «картой» 'a -> (a -> b -> c) -> b -> c' over' [b] ' – zerkms

ответ

5

Это очень похоже на вопрос о домашнем задании. Если да, я настоятельно рекомендую вам попробовать и ответить на этот вопрос для себя. Сказав это, я проведу вас через то, как я сформулирую ответ на этот вопрос, и, надеюсь, вы получите некоторое представление о том, как вы должны подходить к таким вопросам.

Мы знаем, что mapNew имеет тип a -> (a -> b -> c) -> [b] -> [c]. Это очень похоже на существующую функцию Prelude map :: (a -> b) -> [a] -> [b]. Поэтому мы, вероятно, хотим написать наш ответ в терминах map.

mapNew :: a -> (a -> b -> c) -> [b] -> [c] 
mapNew a f bs = ... 

Мы всегда начинаем выписав функцию с аргументами он принимает, так что мы можем увидеть, какие части мы должны работать. Зная, что у нас есть только один a и нужно всегда передавать его f для каждого элемента b в bs, мы можем добавить предложение where для этого частичного применения:

mapNew :: a -> (a -> b -> c) -> [b] -> [c] 
mapNew a f bs = ... 
    where fa :: b -> c 
      fa = f a 

Учитывая это, мы можем теперь записать наш ответ с точки зрения map.

mapNew :: a -> (a -> b -> c) -> [b] -> [c] 
mapNew a f bs = map fa bs 
    where fa :: b -> c 
      fa = f a 

Большинство Haskell программистов упростило бы это определение к:

mapNew :: a -> (a -> b -> c) -> [b] -> [c] 
mapNew a f bs = map (f a) bs 

так (f a) именно частично применяется функция fa. Кроме того, мы можем ЕТ сократить это выражение:

mapNew :: a -> (a -> b -> c) -> [b] -> [c] 
mapNew a f = map (f a) 

Суть этого ответа заключается в утверждении «Зная, что у нас есть только один a и нужно всегда передавать его f для каждого элемента b в bs ». Откуда я знаю это?

Из-за параметрического полиморфизма мы не можем проверять любые значения типа a. Это означает, что единственное значение типа a, которое мы нам предоставили, - это тот, который был передан mapNew. Далее, поскольку f принимает один b и производит один c, мы знаем, что мы должны сначала получить b из предоставленного списка, чтобы применить к нему f. Это именно то, что делает map, и, частично применяя f до a, мы получаем первый аргумент, который мы хотим передать, map.

Смежные вопросы