Как создать структуру данных на Haskell, содержащую поливариадные функции? - PullRequest
0 голосов
/ 04 июля 2018

Как мне набрать и реализовать run, чтобы работали следующие операторы?

data Run = Run {run :: ??}

f1 = Run (\x -> x)
f2 = Run (\x y-> x+y)
f3 = Run (\x y z -> x*(y+z))

print $ run f1 1 :: Int --> 1
print $ run f2 1 2 :: Int --> 3
print $ run f3 1 2 3 :: Int -> 5

Все поливариадные функции в Run имеют тип Int -> ... -> Int: они принимают переменное число аргументов Int и выдают Int.

Если проще, я мог бы жить с решением, имеющим максимальное количество аргументов, например 3:

data Run
  = Run1 (Int -> Int)
  | Run2 (Int -> Int -> Int)
  | Run3 (Int -> Int -> Int -> Int)

f1 = Run1 (\x -> x)
f2 = Run2 (\x y-> x+y)
f3 = Run3 (\x y z -> x*(y+z))

Как бы вы реализовали run?

1 Ответ

0 голосов
/ 04 июля 2018

Так как f1 и f2 в вашем коде имеют одинаковый тип Run, средство проверки типов не может различить run f1 и run f2, которые должны иметь одинаковый тип.

Это затрудняет правильную реализацию переменных функций.

Гораздо проще использовать

data Run a = Run { run :: a }

, чтобы f1 и f2 больше не имели общий тип.

Если вас интересуют только функции Int -> ... -> Int, могут быть некоторые решения, использующие семейства типов, GADT, DataKinds и тому подобное. Это может быть излишним, в зависимости от того, что вы пытаетесь реализовать.

...