Итак, я работаю над забавным экспериментом в контекстном смысле, и я натыкаюсь на стену. Я пытаюсь определить тип данных, который может быть либо примитивом, либо функцией, которая преобразуется из одного конструктора в другой.
data WeaponPart =
WInt Int |
WHash (Map.Map String Int) |
WNull |
WTrans (WeaponPart -> WeaponPart)
instance Show WeaponPart where
show (WInt x) = "WInt " ++ (show x)
show (WHash x) = "WHash " ++ (show x)
show (WTrans _) = "WTrans"
show WNull = "WNull"
cold :: WeaponPart -> WeaponPart
cold (WInt x) = WHash (Map.singleton "frost" x)
cold (WHash x) = WHash $ Map.insertWith (+) "frost" 5 x
cold (WTrans x) = cold $ x (WInt 5)
cold (WNull) = cold $ (WInt 5)
ofTheAbyss :: WeaponPart -> WeaponPart
ofTheAbyss (WTrans x) = x (WTrans x)
Проблема в том, что сигнатура для ofTheAbyss
допускает любую часть оружия в качестве аргумента, тогда как я хочу разрешить только аргументы, созданные WTrans. Вы можете видеть, что я написал только совпадение с образцом для этого случая.
Я пытался использовать GADT, но боюсь, что это была кроличья нора. Никогда не мог заставить их делать то, что я хотел. Есть ли у кого-нибудь идеи, как я могу использовать только аргументы WTrans в ofTheAbyss? Или я просто что-то совсем упускаю.
Спасибо.
Лучший, Эрик