Haskell: 对柯里化数据使用模式匹配
Haskell: Using patten matching with currying data
是否可以使用与柯里化数据匹配的模式?假设如下代码:
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
为值附加名称没有问题。
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
是否可以使用与柯里化数据匹配的模式?假设如下代码:
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
为值附加名称没有问题。
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