2016-01-22 6 views
1

Можно ли использовать сопоставление patten с данными каррирования? Предположим, что следующий код:Haskell: использование соответствия patten с данными каррирования

data Bind = Echo String | Sum Int Int 

getOperation (Echo x) = "Echo" 
getOperation (Sum x y) = "Sum" 

main = getOperation (Sum 1) 

Это терпит неудачу, потому что Sum 1 имеет тип Int -> Bind и getOperation имеет тип Bind -> String.

Мое упоминание состоит в том, чтобы получить строку, которая идентифицирует используемый конструктор данных, даже если данные находятся в карри. Что-то вроде этого поддельного кода:

getOperation (Echo x) = "Echo" 
getOperation (Echo) = "Echo"  -- Pattern matching for curried data 
getOperation (Sum x y) = "Sum" 
getOperation (Sum x) = "Sum"  -- Pattern matching for curried data 
+0

, как вы сами сказали, '' Echo' является String -> Bind' - так прямо сейчас это функция, принимающая «String» и возвращающая «Bind», и, к сожалению, вы не можете использовать функции сопоставления шаблонов (это может быть '\ _-> Sum 0 0', а также для всех' getOperation' знает на этом этапе) – Carsten

ответ

1

Прикрепление имени к значению не представляет проблемы.

data Named a = Named { name :: String, value :: a } 

-- there is a very natural Functor instance for Named as well, which 
-- could be used to implement this 
(<$$>) :: Named (a -> b) -> a -> Named b 
Named n f <$$> x = Named n (f x) 

Вот пример того, как использовать его:

data Bind = Echo String | Add Int Int 

echo :: Named (String -> Bind) 
add :: Named (Int -> Int -> Bind) 
add = Named "Add" Add 
echo = Named "Echo" Echo 

main = do 
    putStrLn . name $ echo 
    putStrLn . name $ echo <$$> "hi" 
    putStrLn . name $ add 
    putStrLn . name $ add <$$> 3 
    putStrLn . name $ add <$$> 3 <$$> 4 

Это производит:

Echo 
Echo 
Add 
Add 
Add