Предположим, data MyAlgebraicType :: Foo Int | Bar Int
. Если у меня есть переменная типа MyAlgebraicType
, как определить, является ли она типом Foo Int
или Bar Int
?
Определение типа алгебраической структуры данных
Ответы (2)
Использование case
:
let var = Bar 42 in
case var of
Foo _ -> putStrLn "It's a Foo!"
Bar _ -> putStrLn "It's a Bar!"
Эти _
можно заменить именем переменной, чтобы связать содержащееся Int
.
Вы также можете использовать определение сопоставления с образцом (которое встречается чаще, чем case
):
tellMeIt :: MyAlgebraicType -> IO ()
tellMeIt (Foo _) = putStrLn "It's a Foo!"
tellMeIt (Bar _) = putStrLn "It's a Bar!"
person
luqui
schedule
20.10.2018
Сопоставление с образцом обычно лучше, но в некоторых случаях код может быть легче читать с помощью таких функций:
isFoo :: MyAlgebraicType -> Bool
isFoo (Foo _) = True
isFoo _ = False
isBar :: MyAlgebraicType -> Bool
isBar (Bar _) = True
isBar _ = False
person
Chai T. Rex
schedule
20.10.2018
Идиома:
isBar x = is [ () | Bar{} <- [x] ]
(где is = not . null
). К сожалению, это очень шумная идиома.
- person luqui; 20.10.2018
Foo Int
иBar Int
, так как это не так. Здесь толькоMyAlgebraicType
является типом. Обычно мы вызываем конструкторыFoo
иBar
. Более неформально можно спросить, как определить форму значения в алгебраическом (данные) типе? - person chi   schedule 20.10.2018