меня тип данных пользовательского схематически определены следующим образом:Приложить типа к функции
data Foo = Foo
{ f1 :: Int
, f2 :: b
, f3 :: c
}
Что мне нужно сделать
Закрепить строку каждой функции, записанной в Foo. Это было довольно ясно в моей голове, что это было тривиально из-за полиморфизма haskell.
Сначала попробуйте: классы
class Value a where
val :: a -> String
class Query e where
queries :: (Value a) => [(e -> a, String)]
instance Value Int where val = show
instance Query Foo where
queries =
[ (f1, "function one")
, (other records of Foo…)
]
Который не работает. Я не уверен, что понял, почему. Но я думаю, что ghc ожидает функцию типа (Foo -> a), но получает функцию типа (Foo -> Int). Итак, здесь не применяется полиморфизм.
Вторая попытка: шаблон соответствия
keyOf :: (Foo -> a) -> String
keyOf f1 = "function one"
keyOf f2 = "function two"
keyOf f3 = "function three"
keyOf _ = "unknown function"
я был вполне удовлетворен, видя, что компилируется. Тогда, в GHCI:
λ keyOf f2 = "function one"
Может не шаблон матч против имени функции, очевидно ...
EDIT: Почему я должен сделать это
Построить строку запроса, как это:
"(keyOf f1)=(f1 Foo), (keyOf f2)=(f2 Foo), (keyOf f3)=(f3 Foo)"
В более общем плане, свернуть каждую функцию r ecorded в Foo с связанной с ним строкой, и это результат. Пример:
exampleFoo :: Foo
exampleFoo = Foo "one" "two" "three"
assocs = [(f1, "function one"), (f2, "function two"), (f3, "function three")]
result == "function one=one, function two=two, function three=three"
Теперь я действительно интересно, если что-то трюк выполнимо без привлечения мета-программирования (например, TemplateHaskell) в Haskell. Любые варианты, которые я не рассматривал? Спасибо.
Можете ли вы привести пример программы, которую вы хотите написать, используя строки, прикрепленные к каждой функции? –
Да, я редактировал вопрос. Это достаточно ясно? – qleguennec
Боюсь, что нет - я не могу понять, что вы имеете в виду в строке запроса. Может быть яснее с некоторым примером кода или псевдокодом. –