How are these two functions parsed?
> (** (1/2)) $ 40
6.324555320336759
it :: Double
> ((**) (1/2)) $ 40
9.094947017729282e-13
it :: Double
The first one is a right section, and is shorthand for:
(\x -> x ** (1/2)) 40
The second one is using the function form of the operator **, essentially treating it as if it were a named function like pow or something:
(**) (1/2) 40
which equals
(1/2) ** 40
I've omitted the $s from your code because they are redundant.
(foo bar) $ baz = (foo bar) baz = foo bar baz
Related
I have a class defined like this, so that foo takes a generic type and returns an Integer:
class Foo a where
foo :: a -> Integer
and a couple of instances defined so it will work with Bool and Char types:
instance Foo Bool where
foo _ = 10
instance Foo Char where
foo _ = 20
If I now want to add an instance for a list with a generic type, I would want to do something like this:
instance Foo [a] where
foo (t:ts) = (foo t) + (foo ts)
However, this is wrong. From my current understanding, I would want to assume that Haskell infers the types and does something like this:
foo [False,True] -> foo False + foo True -> 10 + 10 = 20
I've looked at several books and read about polymorphism and typeclasses, including Learn You a Haskell For Great Good! but still can't wrap my head around how to solve this?
You need to say that the list must contain Foo values:
instance Foo a => Foo [a] where
foo (h:t) = foo h + foo t
foo [] = 0
You can only call foo h when h is a Foo instance, so you need to qualify the type class for [a] so that it only works for lists of Foo instances.
Otherwise, if, for instance, you had a [Int], foo h would imply that you'd try to call foo on an Int value, but foo isn't defined for that type.
With the above implementation for [a] you get expected results:
Prelude> foo [True,False,True]
30
Prelude> foo [True,False,True,True]
40
Prelude> foo "foo"
60
You forgot the base case:
instance Foo a => Foo [a] where
foo (t:ts) = foo t + foo ts
foo [] = 0
Mind that the call foo ts does not mean that we call foo on the second element. We actually call recursively the function we define (the foo in boldface), and this will thus keep calling foo on the elements of the list, until the list is exhausted, in which case the base case foo [] = 0 will be used.
So it will evaluate:
foo (False : True : [])
-> foo False + foo (True : [])
-> 20 + foo (True : [])
-> 20 + foo True + foo []
-> 20 + 20 + foo []
-> 20 + 20 + 0
-> 20 + 20
-> 40
->
I have the following function:
digits :: Int -> [Int]
digits n = go n []
where go num acc
| num < 10 = num : acc
| otherwise = go (div num 10) (mod num 10 : acc)
Is it possible to replace the parentheses in the otherwise expression with $?
The problem
You can't use $ for that. The purpose of $ is to make function application bind as un-tighly as possible, as opposed to normal function application which binds most tightly,
> :i $
($) :: (a -> b) -> a -> b
infixr 0 $
(some irrelevant stuff removed...)
Here, infixr denotes that the operator is right associative, as opposed to infixl which denotes that the operator is left associative. 0 denotes the precedence of the operator. 0 binds least tightly and 9 binds most tightly.
If we write go $ div num 10 $ mod num 10 : acc, this is interpreted as go (div num 10 (mod num 10 : acc)), i.e: passing mod num 10 : acc as the third argument of div, and the result of applying div as the only argument to go.
Solution: the (&) operator
Instead of using the dollar sign, $, for the left hand side, you can instead use &.
> :i &
(&) :: a -> (a -> b) -> b -- Defined in `Data.Function'
infixl 1 &
And now we get:
import Data.Function ((&))
digits :: Int -> [Int]
digits n = go n []
where go num acc
| num < 10 = num : acc
| otherwise = div num 10 & go $ mod num 10 : acc
Solution: apply go infix
You could also use go infix:
digits :: Int -> [Int]
digits n = go n []
where go num acc
| num < 10 = num : acc
| otherwise = div num 10 `go` (mod num 10 : acc)
In this case, the parenthesis on the right hand side is needed due to (:) which is also infix and interferes with go.
Which solution to use
In my opinion, if you can use infix application without parenthesizes, do that. In the case of having a parenthesis on any side such as in: div num 10 `go` (mod num 10 : acc), it may still be warranted to use infix. This is mainly due to readability, as the average reader may not be familiar with &. This notation is (probably) not very commonly used, which is why the average reader is not very familiar with it (and so we have a cycle...).
On the usage of $$
I believe Alexey Romanov's operator, $$ is quite neat as well. Unfortunately, it suffers the same problems as & does: lack of familiarity. Hopefully, his operator can be added to Data.Function in due time and perhaps we can expand our toolbox.
In addition to the answers #Centril mentions, you can replace only the second pair:
go (div num 10) $ mod num 10 : acc
or both, but then you need parentheses in a different place:
(go $ div num 10) $ mod num 10 : acc
or declare another operator like $ but left-associative:
f $$ x = f x
infixl 0 $$
go $$ div num 10 $$ mod num 10 : acc
Considering Haskell has currying functions, we can do this:
foo a b = a + b -- equivalent to `foo a = \b -> a + b`
foo 1 -- ok, returns `\b -> 1 + b`
foo 1 2 -- ok, returns 3
Declaring the function returning a lambda, just like in the comment, works just fine as well.
But when I compose these functions, like this:
foo a b = a + b
bar x = x * x
bar . foo 1 -- ok, returns a lambda
bar . foo 1 2 -- wrong, I need to write `(bar . foo 1) 2`
Then it results in an error.
The question is: why are the parentheses around the function composition necessary?
Let's assume that you've define the following in GHCi:
λ> let foo a b = a + b
λ> let bar x = x * x
Based on some of your follow-up comments, it seems that you believe
bar . foo 1 2
to be equivalent to
(bar . foo 1) 2
However, remember that function application (space) has higher precedence than the composition operator (.); therefore
bar . foo 1 2
is really equivalent to
bar . ((foo 1) 2)
Now, let's look at the types:
. has type (b -> c) -> (a -> b) -> a -> c; its two arguments are functions (that can be composed).
bar has type Num a => a -> a, and is therefore compatible with the type (b -> c) of the first argument of ..
foo 1 2 has type Num a => a; it's a (polymorphic) numeric constant, not a function, and is therefore not compatible with the type (a -> b) of the second argument of ..
That's why you're getting a type error in bar . foo 1 2. What you can do, though, is
bar $ foo 1 2
because the $ operator has type (a -> b) -> a -> b. See Haskell: difference between . (dot) and $ (dollar sign)
bar . foo 1 2 is bar . (foo 1 2) not (bar . foo 1) 2
There's nothing mysterious going on here related to lambdas. Say we expanded the application of foo to 1:
bar . foo 1 2
bar . (\b -> 1 + b) 2
Now, we apply the lambda to the 2
bar . 3
And there is your problem.
Conversely, if we place the parentheses correctly, we evaluate it like this:
(bar . foo 1) 2
(bar . (\b -> 1 + b)) 2
(\x -> bar ((\b -> 1 + b) x)) 2
bar 3
I have a QuickCheck property that looks like this:
prop42 :: Foo -> Bool
prop42 foo = fn1 foo == fn2 foo
If this property fails, it will print out what foo was. But I'd really like to know what fn1 and fn2 returned. And if foo is large, it's kinda non-trivial to generate this information by hand. (I.e., sit there and manually type in the huge wedge of text printed to the Windows console window.)
It's common for testing frameworks to have a thing that compares for equality, and prints out both values if equality didn't hold. But I can't seem to find such a function for QuickCheck...
Take a look at combinators from here. For example, printTestCase allows to add an arbitrary string to the output of failing cases. A quick example:
prop x = let f = sin x
in printTestCase ("Should be at least " ++ show f) $ x >= sin x
$> quickCheck prop
*** Failed! Falsifiable (after 2 tests and 1 shrink):
-1.0
Should be at least -0.8414709848078965
Based on the answer from Yuuri, this is what I went with:
(?==?) :: (Eq x, Show x) => x -> x -> Property
x ?==? y =
printTestCase ("Left: " ++ show x) $
printTestCase ("Right: " ++ show y) $
x == y
Now I can write things like
prop42 :: Foo -> Prop
prop42 foo = fn1 foo ?==? fn2 foo
I think one could do the following, assuming that fn1 and gn2 return Bar:
newtype Bar1 = B1 Bar deriving Show
newtype Bar2 = B2 Bar deriving Show
instance Arbitrary Bar1 where
arbitrary = arbitrary >>= return . B1 . fn1
instance Arbitrary Bar2 where
arbitrary = arbitrary >>= return . B2 . fn2
prop_xx = forAll arbitrary $ \(B1 b1) ->
forAll arbitrary $ \(B2 b2) ->
b1 == b2
This code will compile correctly:
import Text.Printf
import Test.HUnit
doubleMe x = x + x
doubleUs x y = doubleMe x + doubleMe y
doubleSmallNumber x = if x > 100 then x else x*2
doubleSmallNumber' x = if x > 100 then x else x*2 + 1
conanO'Brien = "It's a-me, Conan O'Brien!"
main = do
runTestTT $ TestList [TestCase $ ae 4 $ doubleMe 2,
TestCase $ ae 10 $ doubleUs 2 3,
TestCase $ ae 4 $ doubleSmallNumber 2,
TestCase $ ae 1000 $ doubleSmallNumber' 1000,
TestCase $ assertEqual "" "It's a-me, Conan O'Brien!" conanO'Brien]
where ae = assertEqual ""
The output is:
$ clear && ghc baby.hs && ./baby
[1 of 1] Compiling Main ( baby.hs, baby.o )
Linking baby ...
ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog
Cases: 5 Tried: 5 Errors: 0 Failures: 0
When I change the code to:
import Text.Printf
import Test.HUnit
doubleMe x = x + x
doubleUs x y = doubleMe x + doubleMe y
doubleSmallNumber x = if x > 100 then x else x*2
doubleSmallNumber' x = if x > 100 then x else x*2 + 1
conanO'Brien = "It's a-me, Conan O'Brien!"
main = do
runTestTT $ TestList [TestCase $ ae 4 $ doubleMe 2,
TestCase $ ae 10 $ doubleUs 2 3,
TestCase $ ae 4 $ doubleSmallNumber 2,
TestCase $ ae 1000 $ doubleSmallNumber' 1000,
TestCase $ ae "It's a-me, Conan O'Brien!" conanO'Brien]
where ae = assertEqual ""
I get:
[1 of 1] Compiling Main ( baby.hs, baby.o )
baby.hs:12:65:
No instance for (Num [Char])
arising from the literal `1000'
Possible fix: add an instance declaration for (Num [Char])
In the first argument of `doubleSmallNumber'', namely `1000'
In the second argument of `($)', namely `doubleSmallNumber' 1000'
In the second argument of `($)', namely
`ae 1000 $ doubleSmallNumber' 1000'
I don't understand why.
Also does anybody have any ideas for fixing the ld warning:
ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog
This is an example of the monomorphism restriction. ae "looks like a value" (doesn't have arguments) and doesn't have an explicit type, so compiler won't infer a polymorphic type for it.
In first example, it gets type Int -> Int -> Assertion (I think).
In the second, from ae "It's a-me, Conan O'Brien!" conanO'Brien it gets the type String -> String -> Assertion. Remember that the type of integer literals is actually Num a => a, and 1000 gets type String from ae, so the compiler needs an instance Num String.
EDITED: This can be fixed by giving an explicit type annotation: where ae :: (Show a, Eq a) => a -> a -> Assertion = assertEqual "". Or by adding arguments to definition (eta-expanding it): where ae x y = assertEqual "" x y.
It's the monomorphism restriction. The ae function is assigned a monomorphic type. Either turn off the restriction or give ae a type signature.
#augustss and #Alexey Romanov are correct. You can see the inferred type for ae if you move it to the top level and remove the last assertion:
*Main> :t ae
ae :: Integer -> Integer -> Assertion
If you keep ae in the where clause, but add a type signature with a more general type, it will work:
main = do
runTestTT $ TestList [TestCase $ ae 4 $ doubleMe 2,
TestCase $ ae 10 $ doubleUs 2 3,
TestCase $ ae 4 $ doubleSmallNumber 2,
TestCase $ ae 1000 $ doubleSmallNumber' 1000,
TestCase $ ae "It's a-me, Conan O'Brien!" conanO'Brien]
where
ae :: (Show a, Eq a) => a -> a -> Assertion
ae = assertEqual ""
Just to add a footnote, it's overloading that's ruled out by the monomorphism restriction. So, this is ok
foo :: String -> b -> b
foo _ b = b
goo :: (Int, Bool)
goo = (moo 2, moo True) where moo = foo "boo"
but this isn't
hoo :: Eq b => String -> b -> b -> Bool
hoo _ b c = b == c
ioo :: (Bool, Bool)
ioo = (moo 2 2, moo True True) where moo = hoo "boo"
Parametric polymorphism is permitted (and has no performance overhead)!