I'm trying to chain together functions via the applicative functor pattern, but I'm having a problem compiling my code:
import Control.Applicative
buildMyList :: Float -> Float -> [Float]
buildMyList ul tick = [p | p <- [0,tick..ul]]
myFunctionChain :: [Float]
myFunctionChain = reverse <$> buildMyList 100 1
When I attempt to compile this I get the following compilation error:
Couldn't match type 'Float' with '[a0]'
Expected type: [[a0]]
Actual type: [Float]
In the return type of call of 'buildMyList'
It seems to me that I haven't managed to match the expected return context with the actual context. Not having enough experience in this area, I cant get any further!
The Applicative could be better explained using bulldMyList.
Assume you want to build an array of square matrix:
[(0,0), (0,1), (0,2), (1, 0) ...]. Using list comprehensions:
buildMyMatrix :: Int -> Int -> [(Int, Int)]
buildMyMatrix maxX maxY = [(x, y) | x <- [0..maxX], y <- [0..maxY]]
Using applicative combinators it can be rewritten as:
buildMyMatrix maxX maxY = pure (\x y -> (x, y)) <*> [0..maxX] <*> [0..maxY]
And according to applicative laws we can rewrite pure f <*> x = f <$> x, for all f and x:
buildMyMatrix maxX maxY = (\x y -> (x, y)) <$> [0..maxX] <*> [0..maxY]
I had to use slightly more complicated buildMyMatrix, as your buildMyList is too trivial to benefit from Applicative:
buildMyList :: Float -> Float -> [Float]
buildMyList ul tick = [p | p <- [0,tick..ul]]
buildMyList ul tick = id <$> [0,tick..ul] -- [by functor identity law]:
buildMyList ul tick = [0,tick..ul]
Related
Hi I'm trying to sum a list of tuples into a tuple with the foldl function,
I tryed it with using as parameter a lambda expresion but it's giving out a wrong value
here the code:
data Point = Point {x,y :: Float}
sumPoint :: [Point] -> (Float,Float)
sumPoint xs = foldl (\(a,b) x-> (0+a,0+b)) (0.0,0.0) xs
It should come out sumPoint [Point 2 4, Point 1 2, Point (-1) (-2)] = (2.0,4.0)
But im getting (0.0,0.0)
How is this making any sense?
To be a little structural you better define operations among Point type values and then convert the Point type to Tuple wherever needed. Otherwise you may directly use Tuple and discard the Point type.
data Point = Point {x,y :: Float} deriving Show
toTuple :: Point -> (Float, Float)
toTuple p = (x p, y p)
addPts :: Point -> Point -> Point
addPts p q = Point (x p + x q) (y p + y q)
sumPts :: [Point] -> Point
sumPts = foldl addPts (Point 0 0)
So what you need is toTuple . sumPts function.
*Main> :t toTuple . sumPts
toTuple . sumPts :: [Point] -> (Float, Float)
I changed it to
sumPoint xs = foldl (\(a,b) (Point x y)-> (x+a,y+b)) (0.0,0.0) xs
The problem was I was ignoring the x and at 0+a is nothing happening.
I have a list of constants and degrees of a polynomial equation and want to return a list of this composition for a value be applied and then summed. But this list comes as Int and my function expects a list of double.
poly :: [Double] -> [Double] -> [Double -> Double]
poly a b =
let f x y = (*x) . (**y)
in uncurry f <$> zip a b
-- does not work
poly ([1,2,3]:: [Double]) ([1,2,3]:: [Double])
How to cast a list of int to list of double?
You can use fromIntegral, which will convert from any Integral type into any Numeric type (Int, Integer, Rational, and Double).
More here: https://wiki.haskell.org/Converting_numbers
With #4castle and Victoria Ruiz I came up with the following:
poly :: [Int] -> [Int] -> [Double -> Double]
poly = zipWith $ \x y -> (* (fromIntegral x)) . (** (fromIntegral y))
apply :: Double -> [Double -> Double] -> Double
apply x b = sum $ ($x) <$> b
-- l=left limiting, r=right limiting, a=coeficients, b=degrees
solve :: Int -> Int -> [Int] -> [Int] -> [Double]
solve l r a b =
let h = 0.001
linspace = [fromIntegral l,fromIntegral l+h..fromIntegral r]
p = poly a b
area = sum $ map ((*h) . (`apply` p)) linspace
volume = h * (sum $ map ((*pi) . (**2) .(`apply` p)) linspace)
in [area,volume]
I think Haskell compiler with his strong type inference has some peculiarities that can't be directly solved by type cast.
It's my first exercise to understand the classes in Haskell. My problem is how to define the functions that I have declared in the class and how to test them by terminal ghci.
I explain step by step what I did:
type Point2d = (Int, Int) -- point
type Vector2d = (Int, Int) -- vector
data Shape =
Line Point2d Point2d
| Triangle Point2d Point2d Point2d
deriving (Eq, Show)
class ClassShape s where
name :: s -> String
perim :: s -> Int -- given a CShape calculates the perimeter
move :: s -> Vector2d -> s
Now, I declare s as ClassShape instance, by implementing the corresponding functions.
nameShape :: Shape s -> String
nameShape Line = "Line"
nameShape Triangle = "Triangle"
perimShape :: Shape s -> Int
perimShape Line a b = 999 -- ...
perimShape Triangle a b c = 999 -- ...
Here's my problem: how should I declare the functions? I just need to see an "example" to understand the concept.
The error that Haskell returns is:
`Shape' is applied to too many type arguments
In the type signature for `nameShape':
nameShape :: Shape s -> String
`Shape' is applied to too many type arguments
In the type signature for `perimShape':
perimShape :: Shape s -> Int
Then, how do I test the program on Haskell?
Thanks to all.
Note that nameShape function will not work, because there is no Shape s type defined. Remember that s is a type variable. Only if you have defined Shape s type constructor you can use them. You have defined Shape type in your definition but not Shape s. For defining instance of typeclass, you have to do something like this:
instance ClassShape Shape where
name (Line _ _) = "Line"
name (Triangle _ _ _) = "Triangle"
perim (Line x y) = undefined -- Calculate perimiter using x and y
perim (Triangle x y z) = undefined
move (Line x y) = undefined
move (Triangle x y z) = undefined
You have to fill the undefined with working parts.
You're making a common confusion of early Haskell programmers: using two different things which work in related ways (sum types and classes) to do the same thing in two different ways. Thus there are two problems: the "little" problem (what does this error mean?) and the "big" problem (why is your code shaped like this?).
The Little Problem
You wrote Shape s when you meant to just write Shape. The way you have defined Shape, it has kind * (that is, it is a concrete type) rather than kind * -> *, which is the kind of adjectives -- things like "a list of" or "a pair of" which are abstract until you give them a concrete type to modify ("a list of strings" is concrete, "a list of" is abstract). When you write Shape s you are applying Shape as an adjective to a type variable s but it's not an adjective; it's a noun.
That is why you get the error:
`Shape' is applied to too many type arguments
Side note: you may be used to languages where the error message usually is not very well-related to the actual problem. In Haskell usually the compiler tells you exactly what is wrong, as it did in this case.
The Big Problem
Type classes are collections of unrelated types which can do the same things. The type class syntax passes an implicit context as a "constraint", this context can be implicit because it belongs to the type.
You may need to read that last paragraph a few times in a quiet corner. Basically I mean to say that you can do the same thing as a type class with a data constructor for the context:
data EqOrd s = EqOrdLib {getEq :: s -> s -> Bool, getCmp :: s -> s -> Ordering}
-- this is just provided to us as a primitive by Haskell
intEOL :: EqOrd Int
intEOL = EqOrdLib (==) compare
-- but we can then define things like this:
listEOL :: EqOrd x -> EqOrd [x]
listEOL (EqOrdLib base_eq base_cmp) = EqOrdLib list_eq list_cmp where
list_cmp [] [] = EQ
list_cmp (_:_) [] = GT
list_cmp [] (_:_) = LT
list_cmp (x:xs) (y:ys) = case base_cmp x y of
LT -> LT
GT -> GT
EQ -> list_cmp xs ys
list_eq xs ys = list_cmp xs ys == EQ
Now to use that sort of context, you would have to write explicitly:
quicksort :: EqOrd x -> [x] -> [x]
quicksort _ [] = []
quicksort lib (p:els) = quicksort lib lesser ++ [p] ++ quicksort lib greater
where cmp = getCmp lib
p_less_than x = cmp x p == LT
p_gte x = not . p_less_than
greater = filter p_less_than els
lesser = filter p_gte els
See, we explicitly pass in this library of functions lib and explicitly pull out the comparison function cmp = getCmp lib.
Type classes allow us to implicitly pass the library of functions, by stating up-front that the type itself only has one such library. We pass the library as a "constraint", so instead of EqOrd x -> [x] -> [x] you write Ord x => [x] -> [x] with the "fat arrow" of constraints. But secretly it means "when you ask me to use the < function on two values of type x, I know implicitly what library to get that function from and will get that function for you."
Now: you have one type, Shape, so you don't need typeclasses. (Go back to the first paragraph above: Type classes are collections of unrelated types which can do the same things.
If you want to do type classes then instead of the sum-type for Shape, let's define n-dimensional vectors of different types:
class Vector v where
(*.) :: (Num r) => r -> v r -> v r
(.+.) :: (Num r) => v r -> v r -> v r
norm :: (Num r, Floating r) => v r -> r
-- another advantage of type classes is *default declarations* like:
(.-.) :: (Num r) => v r -> v r -> v r
v1 .-. v2 = v1 .+. (-1 *. v2)
data V2D r = V2D r r deriving (Eq, Show)
instance Vector V2D where
s *. V2D x y = V2D (s * x) (s * y)
V2D x1 y1 .+. V2D x2 y2 = V2D (x1 + x2) (y1 + y2)
norm (V2D x y) = sqrt (x^2 + y^2)
data V3D r = V3D r r r deriving (Eq, Show)
instance Vector V3D where
s *. V3D x y z = V3D (s * x) (s * y) (s * z)
V3D x1 y1 z1 .+. V3D x2 y2 z2 = V3D (x1 + x2) (y1 + y2) (z1 + z2)
norm (V3D x y z) = sqrt (x^2 + y^2 + z^2)
Then we can write things like:
newtype GeneralPolygon v r = Poly [v r]
perimeter :: (Num r, Floating r, Vector v) -> GeneralPolygon v r -> r
perimeter (Poly []) = 0
perimeter (Poly (x : xs)) = foldr (+) 0 (map norm (zipWith (.-.) (x : xs) (xs ++ [x])))
translate :: (Vector v, Num r) => GeneralPolygon v r -> v r -> GeneralPolygon v r
translate (Poly xs) v = Poly (map (v .+.) xs)
Making Typeclasses Work For You
Now if you really want to, you can also unwrap your sum-type data declaration into a bunch of data declarations:
data Line = Line Point2d Point2d deriving (Eq, Show)
data Square = Square Point2d Point2d deriving (Eq, Show)
data Triangle = Triangle Point2d Point2d Point2d deriving (Eq, Show)
Now you can do something simple like:
class Shape s where
perim :: s -> Int
move :: s -> Vector2d -> s
Although I should say, you'll run into a problem when you want to do square roots for perimeters (sqrt is in the Floating typeclass, which Int does not have functions for, you'll want to change Int to Double or something).
Learn You a Haskell presents the addStuff function:
import Control.Monad.Instances
addStuff :: Int -> Int
addStuff = do
a <- (*2) -- binds (*2) to a
b <- (+10) -- binds (+10) to b
return (a+b) -- return has type sig: 'Monad m => a -> m a'
Are the types of a, b, and return (a+b) all Int -> Int? I think so, but I'm not sure how bind-ing plays a role.
I tried to implement it using >>=, but I'm not sure how to complete it (hence ...).
addStuff' :: Int -> Int
addStuff' = (*2) >>= (+10) >>= ...
Please give me a hint to complete it, as well as edit my understanding of the do notation version.
As I understand, the ... needs to include a type of Int -> Int. In the do version, I could use a and b, but I'm not sure how to add them with the >>= version.
When working with the reader monad (a.k.a. the function monad), you have the type a -> b, which can be rewritten as (->) a b. The actual monad instance here is
instance Monad ((->) r) where
return x = const x
f >>= g = \r -> g (f r) r
Notice that during >>=, the type is
(>>=) :: ((->) r a) -> (a -> ((->) r b)) -> ((->) r b)
Which can be rewritten as
(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b)
Or even
(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)
So as you can see, what >>= does is take a single input, apply that to f, and then apply that result to g to produce a new function r -> b. So for your example, you could use:
addStuff' :: Int -> Int
addStuff' = (*2) >>= (+)
And so addStuff' 10 == 30, since it performs the computation (10 * 2) + (10). Note how 10 is fed both to (*2) and (+), and the result of (10*2) is fed to (+) as well. It might make things a little more clear to see it as
test :: Int -> (Int, Int, Int)
test = do
x <- (*2)
y <- (*3)
z <- (*5)
return (x, y, z)
And it's result would be
> test 1
(2, 3, 5)
> test 10
(20, 30, 50)
What this essentially is doing is taking the argument to test "before" it's been applied, feeding it to each of the functions on the right hand side of the <-s, and then combining that result in the return.
So how can you write these without do notation? You could do something like
test :: Int -> (Int, Int, Int)
test =
(\r -> r * 2) >>= (\x ->
(\r -> r * 3) >>= (\y ->
(\r -> r * 5) >>= (\z ->
return (x, y, z))))
Which, admittedly, is not very readable, even with formatting, but the gist is basically that r gets fed to each intermediate function, which produces a result, and a couple nested lambda expressions later you return all three of those results in a tuple.
With a bit of simplification, you could also make each of those nested lambdas into two arguments lambdas:
test =
(\r -> r * 2) >>=
(\x r -> r * 3) >>=
(\y r -> r * 5) >>=
(\z r -> const (x, y, z) r)
I've also replaced the last \z -> return (x, y, z) with its equivalent \z -> const (x, y, z) => \z r -> const (x, y, z) r, just so they all have the same form.
As a rough rule if you want to manually desugar do-notation, first erase the do at the top and flip the bind arrow (<-) on the left-hand-side to a (>>=) on the right-hand-side with the variable on the left as a lambda variable on the right. So:
addStuff :: Int -> Int
addStuff = do
a <- (*2)
... rest ...
Becomes:
addStuff :: Int -> Int
addStuff =
(*2) >>= (\a ->
... rest ...
)
This is recursive, so the next term in the do-notation then becomes nested in the lambda of the desugared term above it, all the way down to the last expression which is just the body of the nested lambda expression.
The desugaring is quite mechanical, it's defined by the following rewrites, where ; denotes a newline.
do { a <- f ; m } ≡ f >>= \a -> do { m }
do { f ; m } ≡ f >> do { m }
do { m } ≡ m
Both a and b are of type Int while return (a+b) has type Int -> Int which is the last term in the do-notation so it has to be identical to the toplevel signature. Using -XScopedTypeVariables we can manually annotate the subterms:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.Instances
addStuff :: Int -> Int
addStuff = do
(a :: Int) <- (*2)
(b :: Int) <- (+10)
(return (a+b)) :: Int -> Int
Thanks to bheklilr.
I wrote my own code.
addStuff :: Int -> Int
addStuff = (\r -> r * 2) >>= (\x ->
(\r -> r + 10) >>= (\y ->
return (x + y)))
I'd like to define a tuple (x, y) as an instance of Enum class, knowing that both x and y are instances of Enum. A following try:
instance (Enum x, Enum y) => Enum (x, y) where
toEnum = y
enumFrom x = (x, x)
only results in error (y not in scope). I'm new to Haskell, could somebody explain how to declare such an instance?
instance (Enum x, Enum y) => Enum (x, y) where
In the above line, x and y are both types (type variables).
toEnum = y
enumFrom x = (x, x)
In the above two lines, x and y are both values ((value) variables). y-as-a-value has not been defined anywhere, that's what it not being in scope means.
As to how to declare such an instance, I'm not sure how you'd want fromEnum and toEnum to behave, for example.
Not a good idea if you ask me, but anyway —
To make an instance of a type class, you need to look at the signatures.
class Enum a where
succ :: a -> a
pred :: a -> a
toEnum :: Int -> a
fromEnum :: a -> Int
enumFrom :: a -> [a]
enumFromThen :: a -> a -> [a]
enumFromTo :: a -> a -> [a]
enumFromThenTo :: a -> a -> a -> [a]
So in your case
toEnum :: Int -> (x, y)
but toEnum = y isn't even defined, because y is just a type, not a value or constructor. Possibilities would be
toEnum n = (toEnum 0, toEnum n)
or
toEnum n = (toEnum n, toEnum n)
or
toEnum n = (toEnum $ n`div`2, toEnum $ (n+1)`div`2)
As for enumFrom, your version has signature
enumFrom :: a -> (a,a)
but we need
enumFrom :: (x,y) -> [(x,y)]
what definition is suitable depends on how toEnum was defined; for my first suggestion it would be
enumFrom (x,y) = [ (x,y') | y' <- enumFrom y ]
Reading Dietrich Epp's comment
It's not actually possible to create a useful Enum (x, y) from Enum x and Enum y. You'd need additional context, like Bounded x, Bounded y, Enum x, Enum y => Enum (x, y).
I thought about ways it could actually be done meaningfully. It seems possible sure enough, a bijection ℤ → ℤ2 exists. My suggestion:
[ ...
, (-3,-3), (-3,-2), (-2,-3), (-3,-1), (-1,-3), (-3,0), (0,-3), (-3,1), (1,-3), (-3,2), (2,-3), (-3,3), (3,-3)
, (-2,3), (3,-2), (-1,3), (3,-1)
, (-2,-2), (-2,-1), (-1,-2), (-2,0), (0,-2), (-2,1), (1,-2), (-2,2), (2,-2)
, (-1,2), (2,-1)
, (-1,-1), (-1,0), (0,-1), (-1,1), (1,-1)
, (0,0)
, (1,0), (0,1), (1,1)
, (2,0), (0,2), (2,1), (1,2), (2,2)
, (3,0), (0,3), (3,1), (1,3), (3,2), (2,3), (3,3)
, ... ]
Note that this reduces to a bijection ℕ → ℕ2 as well, which is important because some Enum instances don't go into the negative range and others do.
Implementation:
Let's make a plain (Int,Int) instance; it's easy to generalize that to your desired one. Also, I'll only treat the positive cases.
Observe that there are k^2 tuples between (0,0) and (excluding) (k,0). All other tuples (x,y) with max x y == k come directly after it. With that, we can define fromEnum:
fromEnum (x,y) = k^2 + 2*j + if permuted then 1 else 0
where k = max x y
j = min x y
permuted = y>x
for toEnum, we need to find an inverse of this function, i.e. knowing fromEnum -> n we want to know the parametes. k is readily calculated as floor . sqrt $ fromIntegral n. j is obtained similarly, simply with div 2 of the remainder.
toEnum n = let k = floor . sqrt $ fromIntegral n
(j, permdAdd) = (n-k^2) `divMod` 2
permute (x,y) | permdAdd>0 = (y,x)
| otherwise = (x,y)
in permute (k,j)
With fromEnum and toEnum, all the other functions are rather trivial.