Haskell $ operator in practical use - haskell

I am trying to get my head around in Haskell expressions using $ operator. Specifically on how to write this in Haskell using $ operator or another if required:
add 1 (add (subtract 2 4) (subtract 8 16))
I managed to remove two paren groups as in:
add 1 $ add (subtract 2 4) $ subtract 8 16
But still need to remove the last pair.
Any ideas?

You can try infix form
add 1 $ subtract 2 4 `add` subtract 8 16
EDIT
There is other way.
Lets define:
newtype W a = W { w :: a }
pure' = W
(.$.) :: W (a -> b) -> a -> W b
(.$.) (W a) b = W $ a b
and operation to use for example
plus :: Int -> Int -> Int
plus = (+)
Then we can do next
foo :: Int
foo = w $ pure' plus .$. plus 1 2 .$. 2
It is basically applicative functor (you can google it for examples) just with different names.
You prefix your operation with w $ pure' and separate arguments with .$..

Related

Accessing self-defined Datatypes - Lambda function application order

Got this:
data Cmd = PushK Int | Pop | Push Int
deriving (Eq,Show)
type StackProgram = [Cmd]
Question:
How can I access the Int value of PushK?
> head [PushK 5, Pop]
PushK 5 -- Great!
> (\_ x -> x)PushK 5
5 -- Great!
> (\_ x -> x)(head [PushK 5, Pop])
Couldn't match expected type `t1 -> t' with actual type `Cmd'
Anyone have a solution?
You unwrap values out of a data constructor by using pattern matching, or by defining record syntax (in which case Haskell generates the getters itself).
Pattern matching
Since here the type is not defined as record, we thus have to use pattern matching:
getK :: Cmd -> Int
getK (PushK x) = x
-- ...
and probably you need to handle the cases of another data constructor.
We can also perform this pattern matching with a lambda expression:
(\(PushK x) -> x) (PushK 5)
Records
We can also define the command as a record:
data Cmd = PushK { k :: Int } | Pop | Push { p :: Int } deriving (Eq,Show)
Now Haskell has generated two functions k :: Cmd -> Int and p :: Cmd -> Int automatically, so in that case we can write:
k (PushK 5)
which will return 5.
Why did (\_ x -> x) PushK 5 return 5?
In Haskell functions are first class citizens. That means you can pass functions as arguments, return them as result. You here did not constructed a Cmd.
In fact PushK is a data constructor, and a function (with type Int -> Cmd), you thus called the lambda expression with two parameters: the first one is the pushK, and the second is 5. You simply omit the first parameter, and retun the second x.
But it is thus derived as:
(\y x -> x) PushK 5
= ((\y -> (\x -> x)) PushK) 5 -- (more verbose version)
-> (\x -> x) 5
-> 5
You may want to define a single catamorphism to deconstruct an arbitrary Cmd value.
cmdCata :: (Int -> a) -- Function to apply to x in (PushK x)
-> a -- Value to replace Pop
-> (Int -> a) -- Function to apply to x in (Push x)
-> Cmd -- The value to deconstruct
-> a -- The result
cmdCata f _ _ (PushK x) = f x
cmdCata _ x _ Pop = x
cmdCata _ _ f (Push x) = f x
It takes two functions and a default value (for Pop) to turn any Cmd value into a value of type a. The following extracts the value wrapped by PushK or Push and rewraps it with Just (the function for PushK doing a little extra work just to show the difference between PushK and Push), and replaces Pop with Nothing.
> cmdCata (Just . (+3)) Nothing Just (PushK 5)
Just 8 -- 5 + 3
> cmdCata (Just . (+3)) Nothing Just Pop
Nothing
> cmdCata (Just . (+3)) Nothing Just (Push 20)
Just 20
Or if you just want an integer and a default value for Pop is fine:
> cmdCata id 0 id (PushK 5)
5
> cmdCata id 0 id Pop
0
> cmdcata id 0 id (Push 3)
3
Compare cmdCata to Data.Maybe.maybe, and think of what functions analogous to Data.Maybe.fromJust, Data.Maybe.catMaybes, etc, could be defined for your Cmd type.

How to use "bind" keyword instead of ">>=" operator in Haskell

I'm trying to understand Haskell monads and wrote this test program, which compiles and works as expected:
divide :: Int -> Int -> Either String Int
divide _ 0 = Left "Divide by zero error
divide numerator denom = Right (numerator `div` denom)
processNumsMonadically :: Int -> Int -> Either String Int
processNumsMonadically n d = divide n d >>= \q -> return (q+1)
When I try using the word bind instead of the >>= operator in the latter function definition:
processNumsMonadically n d = bind (divide n d) (\q -> return (q+1))
I get the error:
Not in scope: 'bind'
What is the correct way to use the word bind?
This isn't a part of Prelude; it resides in Control.Monad.Extra, a part of monad-extras package.
However, you can call operators in prefix manner (like named functions) easily:
processNumsMonadically n d = (>>=) (divide n d) (\q -> return (q+1))
You could also just use do notation:
processNumsMonadically n d = do
q <- divide n d
return (q+1)
But while we're at it, I'd write using a Functor:
processNumsMonadically n d = fmap (+1) (divide n d)
or Applicative syntax:
processNumsMonadically n d = (+1) <$> divide n d
You could also lift the +1 to avoid the need for return and the lambda.
As a personal style remark, bind used as a word isn't idiomatic, and IMHO you shouldn't use it.

Haskell - How to use a function that returns 'Maybe Int' as an argument to another function?

When I have the two functions:
a)
three :: Int -> Maybe Int
three a
| a == 3 = Just 3
| otherwise = Nothing
b)
takeOne :: Int -> Int
takeOne a = (a - 1)
how do I call function a as a parameter to function b? i.e How do I let function b accept a 'Maybe Int' in place of an 'Int'?
At the minute when I try
takeOne (three 3)
I get the error:
ERROR - Type error in application
*** Expression : takeThree (three 3)
*** Term : three 3
*** Type : Maybe Int
*** Does not match : Int
Thanks.
You've got a few options, but I'd say the easiest is fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
Example:
> fmap takeOne $ three 3
Just 2
> fmap takeOne $ three 2
Nothing
Another option would be to use the function maybe, which takes a default value, a function to apply to any value inside the Just, and then the Maybe a to apply this to. An example should make it clear
> maybe 0 takeOne $ three 3
2
> maybe 0 takeOne $ three 2
0
Another alternative if you just want to give a default value is to use the function fromMaybe from Data.Maybe:
> import Data.Maybe
> fromMaybe 0 $ three 3
3
> fromMaybe 0 $ three 2
0
In Haskell, there is a typeclass called Functor defined as
class Functor f where
fmap :: (a -> b) -> f a -> f b
There are many, many types that are instances of Functor. In fact, all parametrized data structures are Functors, as are all Applicatives and Monads. The easiest mental model of a Functor is that it's just a fancy name for a container. For lists, fmap = map, for example. All it does is map a function over the elements inside a container.
Some more examples are:
> fmap (+1) (Left "error")
Left "error"
> fmap (+1) (Right 1)
Right 2
> x <- fmap (++", world") getLine
Hello
> x
Hello, world
> fmap (+1) [1..5]
[2,3,4,5,6]
> fmap (+1) ("fst", 2)
("fst", 3)
Even functions are Functors! Here fmap = (.), it's just normal function composition:
> let lengthPlusOne = fmap (+1) length
> lengthPlusOne "Hello"
6
One other option of course is to write your own.
data IAcceptedAMaybeInt = GotAnswer Int | NothingAtTheMoment deriving Show
pleaseAcceptAMaybeInt f g a = case g a of
Just b -> GotAnswer (f b)
otherwise -> NothingAtTheMoment
Output:
*Main> pleaseAcceptAMaybeInt takeOne three 3
GotAnswer 2
*Main> pleaseAcceptAMaybeInt takeOne three 2
NothingAtTheMoment

Show basic arithmetic functions as string

for a homework assignment, a subtask is to make the arithmetic functions (+), (-), (*) and div showable.
We're solved the rest of the assignment, but we're stuck here. Right now we're using the solution to this question here to distinguish between the operations:
showOp op = case op 3 3 of
6 -> "plus"
0 -> "minus"
9 -> "times"
1 -> "divide"
_ -> "undefined"
However, this strikes me as kind of ugly as things like showOp (\a b -> a * 3 - y) yield "plus".
Is there any way to better distinguish between the operators?
We are using winhugs atm with the appropriate switches -98 +o in order to be able to use the needed extensions.
Edit:
As requested, the actual assignment has to do with Arrays (specifically Array Int (Int -> Int -> Int)). It has to do with generating arrays of operators that fulfill certain conditions.
The assignment states:
Make the data type Array Int (Int->Int-Int) an Instance of Show. The arithmetic operations from the previous exercises should be represented as "plus", "minus", "times" and "div".
thx for any help in advance
Use induction :)
{-# LANGUAGE FlexibleInstances #-}
instance Eq (Int-> Int -> Int) where
f == g = induce f g where
base = 1
n = 2
induce f g = and [f 1 n' == g 1 n' | n' <- [base, n, n+1]]
instance Show (Int-> Int -> Int) where
show a = showOp a where
showOp op = case lookup op ops of
Just a -> a
otherwise -> "undefined"
ops = [((+),"plus")
,((-),"minus")
,((*),"times")
,(div,"divide")]
Output:
*Main> (\a b -> a * 3 - b) :: (Int->Int->Int)
undefined

What can be improved on my first haskell program?

Here is my first Haskell program. What parts would you write in a better way?
-- Multiplication table
-- Returns n*n multiplication table in base b
import Text.Printf
import Data.List
import Data.Char
-- Returns n*n multiplication table in base b
mulTable :: Int -> Int -> String
mulTable n b = foldl (++) (verticalHeader n b w) (map (line n b w) [0..n])
where
lo = 2* (logBase (fromIntegral b) (fromIntegral n))
w = 1+fromInteger (floor lo)
verticalHeader :: Int -> Int -> Int -> String
verticalHeader n b w = (foldl (++) tableHeader columnHeaders)
++ "\n"
++ minusSignLine
++ "\n"
where
tableHeader = replicate (w+2) ' '
columnHeaders = map (horizontalHeader b w) [0..n]
minusSignLine = concat ( replicate ((w+1)* (n+2)) "-" )
horizontalHeader :: Int -> Int -> Int -> String
horizontalHeader b w i = format i b w
line :: Int -> Int -> Int -> Int -> String
line n b w y = (foldl (++) ((format y b w) ++ "|" )
(map (element b w y) [0..n])) ++ "\n"
element :: Int -> Int -> Int -> Int -> String
element b w y x = format (y * x) b w
toBase :: Int -> Int -> [Int]
toBase b v = toBase' [] v where
toBase' a 0 = a
toBase' a v = toBase' (r:a) q where (q,r) = v `divMod` b
toAlphaDigits :: [Int] -> String
toAlphaDigits = map convert where
convert n | n < 10 = chr (n + ord '0')
| otherwise = chr (n + ord 'a' - 10)
format :: Int -> Int -> Int -> String
format v b w = concat spaces ++ digits ++ " "
where
digits = if v == 0
then "0"
else toAlphaDigits ( toBase b v )
l = length digits
spaceCount = if (l > w) then 0 else (w-l)
spaces = replicate spaceCount " "
Here are some suggestions:
To make the tabularity of the computation more obvious, I would pass the list [0..n] to the line function rather than passing n.
I would further split out the computation of the horizontal and vertical axes so that they are passed as arguments to mulTable rather than computed there.
Haskell is higher-order, and almost none of the computation has to do with multiplication. So I would change the name of mulTable to binopTable and pass the actual multiplication in as a parameter.
Finally, the formatting of individual numbers is repetitious. Why not pass \x -> format x b w as a parameter, eliminating the need for b and w?
The net effect of the changes I am suggesting is that you build a general higher-order function for creating tables for binary operators. Its type becomes something like
binopTable :: (i -> String) -> (i -> i -> i) -> [i] -> [i] -> String
and you wind up with a much more reusable function—for example, Boolean truth tables should be a piece of cake.
Higher-order and reusable is the Haskell Way.
You don't use anything from import Text.Printf.
Stylistically, you use more parentheses than necessary. Haskellers tend to find code more readable when it's cleaned of extraneous stuff like that. Instead of something like h x = f (g x), write h = f . g.
Nothing here really requires Int; (Integral a) => a ought to do.
foldl (++) x xs == concat $ x : xs: I trust the built-in concat to work better than your implementation.
Also, you should prefer foldr when the function is lazy in its second argument, as (++) is – because Haskell is lazy, this reduces stack space (and also works on infinite lists).
Also, unwords and unlines are shortcuts for intercalate " " and concat . map (++ "\n") respectively, i.e. "join with spaces" and "join with newlines (plus trailing newline)"; you can replace a couple things by those.
Unless you use big numbers, w = length $ takeWhile (<= n) $ iterate (* b) 1 is probably faster. Or, in the case of a lazy programmer, let w = length $ toBase b n.
concat ( (replicate ((w+1)* (n+2)) "-" ) == replicate ((w+1) * (n+2)) '-' – not sure how you missed this one, you got it right just a couple lines up.
You do the same thing with concat spaces, too. However, wouldn't it be easier to actually use the Text.Printf import and write printf "%*s " w digits?
Norman Ramsey gave excellent high-level (design) suggestions; Below are some low-level ones:
First, consult with HLint. HLint is a friendly program that gives you rudimentary advice on how to improve your Haskell code!
In your case HLint gives 7 suggestions. (mostly about redundant brackets)
Modify your code according to HLint's suggestions until it likes what you feed it.
More HLint-like stuff:
concat (replicate i "-"). Why not replicate i '-'?
Consult with Hoogle whenever there is reason to believe that a function you need is already available in Haskell's libraries. Haskell comes with tons of useful functions so Hoogle should come in handy quite often.
Need to concatenate strings? Search for [String] -> String, and voila you found concat. Now go replace all those folds.
The previous search also suggested unlines. Actually, this even better suits your needs. It's magic!
Optional: pause and thank in your heart to Neil M for making Hoogle and HLint, and thank others for making other good stuff like Haskell, bridges, tennis balls, and sanitation.
Now, for every function that takes several arguments of the same type, make it clear which means what, by giving them descriptive names. This is better than comments, but you can still use both.
So
-- Returns n*n multiplication table in base b
mulTable :: Int -> Int -> String
mulTable n b =
becomes
mulTable :: Int -> Int -> String
mulTable size base =
To soften the extra characters blow of the previous suggestion: When a function is only used once, and is not very useful by itself, put it inside its caller's scope in its where clause, where it could use the callers' variables, saving you the need to pass everything to it.
So
line :: Int -> Int -> Int -> Int -> String
line n b w y =
concat
$ format y b w
: "|"
: map (element b w y) [0 .. n]
element :: Int -> Int -> Int -> Int -> String
element b w y x = format (y * x) b w
becomes
line :: Int -> Int -> Int -> Int -> String
line n b w y =
concat
$ format y b w
: "|"
: map element [0 .. n]
where
element x = format (y * x) b w
You can even move line into mulTable's where clause; imho, you should.
If you find a where clause nested inside another where clause troubling, then I suggest to change your indentation habits. My recommendation is to use consistent indentation of always 2 or always 4 spaces. Then you can easily see, everywhere, where the where in the other where is at. ok
Below's what it looks like (with a few other changes in style):
import Data.List
import Data.Char
mulTable :: Int -> Int -> String
mulTable size base =
unlines $
[ vertHeaders
, minusSignsLine
] ++ map line [0 .. size]
where
vertHeaders =
concat
$ replicate (cellWidth + 2) ' '
: map horizontalHeader [0 .. size]
horizontalHeader i = format i base cellWidth
minusSignsLine = replicate ((cellWidth + 1) * (size + 2)) '-'
cellWidth = length $ toBase base (size * size)
line y =
concat
$ format y base cellWidth
: "|"
: map element [0 .. size]
where
element x = format (y * x) base cellWidth
toBase :: Integral i => i -> i -> [i]
toBase base
= reverse
. map (`mod` base)
. takeWhile (> 0)
. iterate (`div` base)
toAlphaDigit :: Int -> Char
toAlphaDigit n
| n < 10 = chr (n + ord '0')
| otherwise = chr (n + ord 'a' - 10)
format :: Int -> Int -> Int -> String
format v b w =
spaces ++ digits ++ " "
where
digits
| v == 0 = "0"
| otherwise = map toAlphaDigit (toBase b v)
spaces = replicate (w - length digits) ' '
0) add a main function :-) at least rudimentary
import System.Environment (getArgs)
import Control.Monad (liftM)
main :: IO ()
main = do
args <- liftM (map read) $ getArgs
case args of
(n:b:_) -> putStrLn $ mulTable n b
_ -> putStrLn "usage: nntable n base"
1) run ghc or runhaskell with -Wall; run through hlint.
While hlint doesn't suggest anything special here (only some redundant brackets), ghc will tell you that you don't actually need Text.Printf here...
2) try running it with base = 1 or base = 0 or base = -1
If you want multiline comments use:
{- A multiline
comment -}
Also, never use foldl, use foldl' instead, in cases where you are dealing with large lists which must be folded. It is more memory efficient.
A brief comments saying what each function does, its arguments and return value, is always good. I had to read the code pretty carefully to fully make sense of it.
Some would say if you do that, explicit type signatures may not be required. That's an aesthetic question, I don't have a strong opinion on it.
One minor caveat: if you do remove the type signatures, you'll automatically get the polymorphic Integral support ephemient mentioned, but you will still need one around toAlphaDigits because of the infamous "monomorphism restriction."

Resources