We can use type synonym for function definitions, e.g.
type FuncDef = Int -> Int -> Int
This avoids us writing long function definition every time.
Use:
someFunc :: FuncDef -> Int
Instead of
someFunc :: (Int -> Int -> Int) -> Int
which is more readable and less code as well.
Simple algebraic data types are straight forward and easy to do pattern matching etc, e.g.
data AType = X | Y | Z Int
matchType :: AType -> Bool
matchType X = ..
matchType Y = ..
matchType (Z _) = ..
As I look more into Haskell data types, I found we can have function definition in data constructor when defining new type.
data MyType a b = X | Y (a -> b)
This puzzles me a bit and haven't seen many examples of this around. In a way, the idea of high-order function where a function can take another function as argument is similar to this situation, except here it applies to data type. The Haskell wiki does not say much about "high-order data type definition". I realise I may be getting all these terms wrong, so please correct me, and point me to more reading. I really want to see a concrete usage of this. Thanks!
matchMyType :: (MyType a b) -> Bool
matchMyType X = ..
matchMyType Y ?? = ..
You might use this kind of pattern in many situations. For example, if you want a function that transforms strings in various ways, you might have a data type like this (This is just an example that demonstrates the principle - don't write code like this!):
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)
Then, a program that uses this might look like:
-- | 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
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
As C.A.McCann says, there's nothing special about functions really.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With