我们可以使用类型同义词作为函数定义,例如
type FuncDef = Int -> Int -> Int
这避免了我们每次编写长函数定义。
使用:
someFunc :: FuncDef -> Int
而不是
someFunc :: (Int -> Int -> Int) -> Int
更易读,代码也更少。
简单的代数数据类型是直接的,易于进行模式匹配等,例如
data AType = X | Y | Z Int
matchType :: AType -> Bool
matchType X = ..
matchType Y = ..
matchType (Z _) = ..
当我更多地了解Haskell数据类型时,我发现在定义新类型时我们可以在数据构造函数中定义函数。
data MyType a b = X | Y (a -> b)
这让我感到困惑,并没有看到很多这方面的例子。在某种程度上,函数可以将另一个函数作为参数的高阶函数的想法与这种情况类似,除了它适用于数据类型。 Haskell维基没有多说“高阶数据类型定义”。我意识到我可能会把所有这些条款都弄错了,所以请纠正我,并指出我更多阅读。我真的希望看到具体用法。谢谢!
matchMyType :: (MyType a b) -> Bool
matchMyType X = ..
matchMyType Y ?? = ..
答案 0 :(得分:11)
在许多情况下,您可能会使用这种模式。例如,如果你想要一个以各种方式转换字符串的函数,你可能会有这样的数据类型(这只是一个演示原理的例子 - 不要写这样的代码!):
data StringTransformation =
-- | Doesn't transform the string at all
NoTransformation |
-- | Takes the string and generates a suffix that should be appended
Append (String -> String) |
-- | Takes the string and generates a prefix that should be prepended
Prepend (String -> String) |
-- | Takes the string and transforms it arbitrarily to a new string
Map (String -> String)
然后,使用它的程序可能如下所示:
-- | Returns 'True' if the name is male
isMaleName :: String -> Bool
isMaleName = ...
-- | Adds a title to a name, for example "John Smith" -> "Mr. John Smith"
addTitle :: StringTransformation
addTitle =
PrependTransformation $ \ name ->
if isMaleName name
then "Mr. "
else "Mrs. "
-- Applies a string transformation to a 'String'.
transformString :: StringTransformation -> String -> String
transformString NoTransformation str = str
transformString (Append f) str = str ++ f str
transformString (Prepend f) str = f str ++ str
transformString (Map f) str = f str
答案 1 :(得分:4)
data Thingy a b = A b
| B (a -> b)
really :: Thingy a b -> a -> b
really (A x) _ = x -- x :: b
really (B f) y = f y -- f :: a -> b, y :: a, f y :: b
正如C.A.McCann所说,真正的功能没什么特别的。