As you may have noticed, passing input to a function in haskell is simple because of the statically type nature of the language. A function can have a complicated input and output return, but at least you are given the parameters of that particular function. In python you can pass anything to a function; you can pass a function, a integer constant, an instance of a class and yet the function really only expects an boolean.
[2.] Examples
putStrLn :: String -> IO ()
For example, putStrLn expects a string as an input and will return unit in the IO Monad.
>putStrLn "abc"
Will print abc to the console.
Prelude> putStrLn "abc" ++ "123"
:1:0:
Couldn't match expected type `[a]' against inferred type `IO ()'
In the first argument of `(++)', namely `putStrLn "abc"'
In the expression: putStrLn "abc" ++ "123"
In the definition of `it': it = putStrLn "abc" ++ "123"
Prelude>
The following example gave an error. Why? We gave putStrLn three arguments as opposed to the one. Here are the extra arguments, "++" and "123".
To fix the issue:
putStrLn ("abc" ++ "23")
Or even:
(putStrLn ("abc" ++ "23"))
[3.] Dollar Sign, syntatic sugar
We can also use the syntatic sugar, the dollar sign function to alleviate us from having to wrap the arguments in parentheses. Here is the type:
Prelude] :type ($)
($) :: (a -> b) -> a -> b
Pass ($) The infix function has a first input parameter (a -> b), a function and then the 'a' argument which will output b. The following code demonstrates three different calls to putStrLn, but the final output is the same.
Prelude] putStrLn "abc"
abc
Prelude] putStrLn $ "abc"
abc
Prelude] (putStrLn "abc")
abc
Prelude]
Here is another working example:
putStrLn $ "abc: " ++ show(3) ++ show(4)
If we return to the ($) definition and putStrLn.
($) :: (a -> b) -> a -> b
putStrLn represents this part of the input (a -> b)
'a' represents the String input and b represents the output of putStrLn String which is the IO () monad.
For this aspect of the call, "abc: " ++ show(3) ++ show(4);
The (++) operator has the following type definition:
Prelude> :t (++)
(++) :: [a] -> [a] -> [a]
Where [a] can be represented by [Char].
Here are another set of working examples.
Prelude> putStrLn $ "abc: " ++ (show(3) ++ show(4))
abc: 34
Prelude> putStrLn $ ("abc: " ++ (show(3) ++ show(4)))
abc: 34
Prelude> (putStrLn $ ("abc: " ++ (show(3) ++ show(4))))
abc: 34
Prelude> (putStrLn $ ("abc: " ++ (show(3) ++ show(4))))
abc: 34
Prelude> (putStrLn ("abc: " ++ (show(3) ++ show(4))))
abc: 34
Those examples are a little confusing because the (++) operator calls are resulting to one "string" input. For example:
let z = "abc: " ++ show(3) ++ show(4)
Is of type String.
[4.] Function composition
The infix dot operator shown below takes one function, another function and an input and returns the output c.
Prelude] :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
If we used the putStrLn function, and show function; what combinations could we come up with?
Note, show is defined by the following signature.
Prelude] :t show
show :: (Show a) => a -> String
Prelude] putStrLn . show $ 5
5
Prelude]
I will use the following notation to denote the operation invoked above:
### Function: **putStrLn** ||| Type: ( String -> IO () ) ###
infix dot-operator and then:
### Function: **show** ||| Type: ( a -> String ) ###
infix dollar sign operator and then the value of 5.
Prelude] putStrLn . show $ 5
5
Prelude]
The following calls also worked
Prelude> putStrLn $ show 5
5
Prelude> putStrLn (show $ 5)
5
Prelude> putStrLn $ (show $ 5)
5
Prelude> (putStrLn $ (show $ 5))
5
If you are given a list and need to print each element on its own line, you can use the following snippet.
mapM_ (\x -> (putStrLn ("Token: " ++ x ++ " Len: " ++ (show (length x))))) ["ab", "1231", "ddd"]
Do two things to make function composition look easier, think backwards and consider that putStrLn, show and ($) are operations with only one input and one output. As you can see, with haskell are many different ways to do something as simple as invoke a function.
edited: Apparently, I got so carried away, I didn't acknowledge that you can just call the function without any operators. E.g; [ putStrLn $ show 5 ] Sorry if that simple fact wasn't made clear.
No comments:
Post a Comment