Как лучше всего реализовать функцию makeCloths, используя функции высшего порядка? Я надеюсь достичь того, что makeCloths может автоматически заполнять каждый метод в methodsList правильными аргументами, которые предоставлены в materialList. Так что в будущем, если в methodsList будут добавлены дополнительные методы, и методы будут использовать только аргументы в materialList, нам не потребуется изменять код в makeCloths.

data Material = WhiteCloth Int
              | BlueCloth Int
              | RedCloth Int

makeWhiteShirt :: Material -> Clothe
makeWhiteShirt (WhiteCloth x) = .....

makeBluePants :: Material -> Clothe
makeBluePants (BlueCloth x) = .....

makeRedBlueDress :: Material -> Material -> Clothe
makeRedBlueDress (RedCloth x) (BlueCloth y) = ......

methodsList = [ makeWhiteShirt, makeBluePants, makeRedBlueDress ]
materialList = [ WhiteCloth 3, BlueCloth 2, RedCloth 2]

-- call makeCloths like so
-- listOfClothes = makeCloths methodsList materialList 
makeCloths :: [a] -> [b] -> [Clothe]
1
HHC 18 Фев 2013 в 15:24
Как определяется Clothe? Этот код - ваша собственная работа или взят из задания?
 – 
Boris
18 Фев 2013 в 15:29
2
Здесь проблема в том, что makeWhiteShirt имеет тип Material -> Clothe, а makeRedBlueDress имеет тип Material -> Material -> Clothe, поэтому они не могут быть оба в одном списке (все в списке должно имеют один и тот же тип). Кроме того, что произойдет, если я вызову makeWhiteShirt с аргументом RedCloth 1? Выдает ли это ошибку?
 – 
Chris Taylor
18 Фев 2013 в 15:31
# Вопрос Криса, это одна из проблем, с которыми я столкнулся .... Я не знаю, как лучше всего получить кучу информации и кучу методов, которые используют информацию по-другому ... как методы на самом деле находят аргументы это в списке информации
 – 
HHC
18 Фев 2013 в 15:36
Возможно, вы могли бы сделать так, чтобы каждая из функций конструктора принимала список доступных материалов, поэтому каждая подпись была [Material] -> Clothe или, возможно, [Material] -> Maybe Clothe, если вы не уверены, что из доступных материалов можно сделать кусок ткани.
 – 
Boris
18 Фев 2013 в 15:39
# Борис, в настоящее время я занимаюсь финансовым проектом, и у меня есть много методов, которые вычисляют вещи с использованием фиксированных данных, таких как капитал, активы, прибыль в этом году, прибыль в прошлом году и т. Д ... ну, я думаю, makeCloths должен только вызывать методы с правильными аргументами
 – 
HHC
18 Фев 2013 в 15:40

1 ответ

Лучший ответ

Во-первых, как предлагали многие другие, haskell не позволит вам иметь массив функций, мощность которых не совпадает. Вы хотите, чтобы makeRedBlueDress имел тип Material -> Clothe. Если вам действительно нужен такой полиморфизм, ничто не мешает нам определить дополнительный тип для Материала, который принимает несколько аргументов (или состоит из нескольких Материалов).

Как только мы это сделаем, makeCloths станет частным случаем функции zipWith.

makeCloths = zipWith $ \x y -> (x y)

Подпись типа для него имеет наибольший смысл

zipWith $ \x y -> (x y) :: [b -> c] -> [b] -> [c]
3
In-Ho Yi 18 Фев 2013 в 15:58
Ух ты! Это действительно близко к тому, чем я собираюсь заниматься. Однако для вашей модели метод может иметь только один аргумент, если методу требуется несколько аргументов, нам придется изменить тип данных, чтобы он сопровождал его. Но это не будет гибким, если мы хотим часто или динамически изменять список методов. Какие-либо предложения?
 – 
HHC
19 Фев 2013 в 02:18
Очень сложно отнести функции с разной арностью к одной и той же категории. Возможно, вам лучше спроектировать все функции для приема нескольких аргументов, приняв массив, а затем выполнить умное сопоставление с образцом.
 – 
In-Ho Yi
26 Фев 2013 в 11:24