I'm testing this code:
puntosEnCircunferencia :: Float -> (Float , Float) -> [(Float , Float)] -> [(Float , Float)]
puntosEnCircunferencia a y z = filter auxPuntos z
where auxPuntos (w,s) (k,r) = ((k - w)^2 + (r - s)^2) < (a ^ 2)
but it throw me this error:
• Couldn't match type ‘(Float, Float) -> Bool’ with ‘Bool’
Expected type: (Float, Float) -> Bool
Actual type: (Float, Float) -> (Float, Float) -> Bool
• Probable cause: ‘auxPuntos’ is applied to too few arguments
In the first argument of ‘filter’, namely ‘auxPuntos’
In the expression: filter auxPuntos z
In an equation for ‘puntosEnCircunferencia’:
puntosEnCircunferencia a y z
= filter auxPuntos z
where
auxPuntos (w, s) (k, r) = ((k - w) ^ 2 + (r - s) ^ 2) < (a ^ 2)
What im doing wrong. Im starting with Haskell so I don't have much experience to fix this.
Thanks.
puntosCircunferencia takes three arguments: a radius a, a center y, and a list of points z. auxPuntos should test if a single given point is with a distance a of point y, and as such should only take a single argument.
Below, I replace y with a pattern to match the components, as we need those in the definition of auxPuntos.
puntosEnCircunferencia a (x0, y0) zs = filter auxPuntos zs
where auxPuntos (x1, y1) = ((x1-x0)^2 + (y1-y0)^2) < (a^2)
Another (possibly) clearer way to write this is to define a distance function as well.
puntosEnCircunferencia a y zs = filter auxPuntos zs
where auxPuntos p = squareDistance p y < a^2
squareDistance (x0, y0) (x1, y1) = (x1 - x0)^2 + (y1 - y0)^2
(In either case, you can drop zs as an explicit argument:
puntosEnCircunferencia a y = filter auxPuntos
where ...
)
The problem of your code is in the where pattern matching, the ghci tell us:
Expected type: (Float, Float) -> Bool
Actual type: (Float, Float) -> (Float, Float) -> Bool
Now lets get back into your code, you have:
where auxPuntos (w,s) (k,r) = ((k - w)^2 + (r - s)^2) < (a ^ 2)
Above you're calling auxPuntos with 2 parameters (two arrays), but you only have one list of arrays z not two.
filter auxPuntos z
But remember the type of filter is:
filter :: (a -> Bool) -> [a] -> [a]
So we only apply a filter to [a], to solve this we need to add the k and r values into the where:
puntosEnCircunferencia a b z= filter p z
where
k = b !! 0
r = b !! 1
p (w,s)= ((k - w)^2 + (r - s)^2) < a^2
ghci> largestDivisible 1 [2,1] [(1,2),(3,4)]
Related
I am trying to implement my code based almost directly on a paper (pages 34-35). I am using Haskell's Num class instead of the user-defined Number class suggested in the paper.
I want to focus on implementing addition over dynamic time-varying Float values, and subsequently addition over time-varying Points.
Listing 1 is my attempt. How do I get addition of points with time-varying coordinates to work properly? My research requires a review of the code in that particular paper. As far as it is practical, I need to stick to the structure of the original code in the paper. In other words, what
do I need to add to Listing 1 to overload (+) from Num to perform addition on time varying points?
module T where
type Time = Float
type Moving v = Time -> v
instance Num v => Num (Moving v) where
(+) a b = \t -> (a t) + (b t)
(-) a b = \t -> (a t) - (b t)
(*) a b = \t -> (a t) * (b t)
-- tests for time varying Float values, seems OK
a,b::(Moving Float)
a = (\t -> 4.0)
b = (\t -> 5.0)
testA = a 1.0
testAddMV1 = (a + b ) 1.0
testAddMV2 = (a + b ) 2.0
-- Point Class
class Num s => Points p s where
x, y :: p s -> s
xy :: s -> s -> p s
data Point f = Point f f deriving Show
instance Num v => Points Point v where
x (Point x1 y1) = x1
y (Point x1 y1) = y1
xy x1 y1 = Point x1 y1
instance Num v => Num (Point (Moving v)) where
(+) a b = xy (x a + x b) (y a + y b)
(-) a b = xy (x a - x b) (y a - y b)
(*) a b = xy (x a * x b) (y a * y b)
-- Cannot get this to work as suggested in paper.
np1, np2 :: Point (Moving Float)
np1 = xy (\t -> 4.0 + 0.5 * t) (\t -> 4.0 - 0.5 * t)
np2 = xy (\t -> 0.0 + 1.0 * t) (\t -> 0.0 - 1.0 * t)
-- Error
-- testAddMP1 = (np1 + np2 ) 1.0
-- * Couldn't match expected type `Double -> t'
-- with actual type `Point (Moving Float)'
The error isn't really about the addition operation. You also can't write np1 1.0 because this is a vector (I don't particularly like calling it that) whose components are functions. Whereas you try to use it as a function whose values are vectors.
What you're trying to express here is, "evaluate both the component-functions at this time-slice, and give me back the point corresponding to both coordinates". The standard solution (which I don't recommend, though) is to give Point a Functor instance. This is something the compiler can do for you:
{-# LANGUAGE DeriveFunctor #-}
data Point f = Point f f
deriving (Show, Functor)
And then you can write e.g.
fmap ($1) (np1 + np2)
Various libraries have special operators for this, e.g.
import Control.Lens ((??))
np1 + np2 ?? 1
Why is a functor instance a bad idea? For the same reason it's a bad idea to implement multiplication on points as component-wise multiplication†: it does not make sense physically. Namely, it depends on a particular choice of coordinate system, but the choice of coordinate frame is in principle arbitrary and should not affect the results. For addition it indeed does not affect the result (disregarding float inaccuracy), but for multiplication or arbitrary function-mapping it can massively affect the result.
A better solution is to just not use "function-valued points" in the first place, but instead point-valued functions.
np1, np2 :: Moving (Point Float)
np1 = \t -> xy (4.0 + 0.5 * t) (4.0 - 0.5 * t)
np2 t = xy (0.0 + 1.0 * t) (0.0 - 1.0 * t)
†Actually a functor instance is a less bad idea than a Num instance. The particular operation fmap ($1) is in fact equivariant under coordinate transformation. That's because point-evaluation of functions is a linear mapping. To properly express this, you could make Point an endofunctor in the category of linear maps.
I include a renaming approach in Listing 2 and a qualified import approach in Listing 3 .
Listing 2 contains code that I believe is reasonably close to the original code. It was necessary rename the operations in Number by appending (!). This avoids a clash with the operations in Prelude Num class. I believe that there were two errors in the original code. The most serious is in the instance Number (Moving Float) where the same operation symbols are used on the left and right of the equations (e.g. +). The compiler has no way to distinguish these operations. The other error is a syntax error instance Number v => (Point v) there is no class name after =>. In sort the original code will not run, which was the motivation behind the question.
Listing 2
module T where
type Time = Float
type Moving v = Time -> v
class Number a where
(+!), (-!), (*!) :: a -> a -> a
sqr1, sqrt1 :: a -> a
-- Define Number operations in terms of Num operations from Prelude
-- Original code does not distinguish between these operation and will not compile.
instance Number (Moving Float) where
(+!) a b = \t -> (a t) + (b t)
(-!) a b = \t -> (a t) - (b t)
(*!) a b = \t -> (a t) * (b t)
sqrt1 a = \t -> sqrt (a t)
sqr1 a = \t -> ((a t) * (a t))
data Point f = Point f f deriving Show
class Number s => Points p s where
x, y :: p s -> s
xy :: s -> s -> p s
dist :: p s -> p s -> s
dist a b = sqrt1 (sqr1 ((x a) -! (x b)) +! sqr1 ((y a) -! (y b)))
instance Number v => Points Point v where
x (Point x1 y1) = x1
y (Point x1 y1) = y1
xy x1 y1 = Point x1 y1
-- Syntax error in instance header in original code.
instance Number (Point (Moving Float)) where
(+!) a b = xy (x a +! x b) (y a +! y b)
(-!) a b = xy (x a -! x b) (y a -! y b)
(*!) a b = xy (x a *! x b) (y a *! y b)
sqrt1 a = xy (sqrt1 (x a)) (sqrt1 (y a))
sqr1 a = xy (sqr1 (x a)) (sqr1 (y a))
mp1, mp2 :: Point (Moving Float)
mp1 = (xy (\t -> 4.0 + 0.5 * t) (\t -> 4.0 - 0.5 * t))
mp2 = xy (\t -> 0.0 + 1.0 * t) (\t -> 0.0 - 1.0 * t)
movingDist_1_2 = dist mp1 mp2
dist_at_2 = movingDist_1_2 2.0 -- gives 5.83
Listing 3 uses a qualified import as suggested by ben. Note we need an additional instance to define the operations in the Number class using the Num class.
Listing 3
module T where
import qualified Prelude as P
type Time = P.Float
type Moving v = Time -> v
class Number a where
(+), (-), (*) :: a -> a -> a
sqr, sqrt:: a -> a
instance Number P.Float where
(+) a b = a P.+ b
(-) a b = a P.- b
(*) a b = a P.* b
sqrt a = P.sqrt a
sqr a = a P.* a
instance Number (Moving P.Float) where
(+) a b = \t -> (a t) + (b t)
(-) a b = \t -> (a t) - (b t)
(*) a b = \t -> (a t) * (b t)
sqrt a = \t -> sqrt (a t)
sqr a = \t -> ((a t) * (a t))
data Point f = Point f f deriving P.Show
class Number s => Points p s where
x, y :: p s -> s
xy :: s -> s -> p s
dist :: p s -> p s -> s
dist a b = sqrt (sqr ((x a) - (x b)) + sqr ((y a) - (y b)))
instance Number v => Points Point v where
x (Point x1 y1) = x1
y (Point x1 y1) = y1
xy x1 y1 = Point x1 y1
instance Number (Point (Moving P.Float)) where
(+) a b = xy (x a + x b) (y a + y b)
(-) a b = xy (x a - x b) (y a - y b)
(*) a b = xy (x a * x b) (y a * y b)
sqrt a = xy (sqrt (x a)) (sqrt (y a))
sqr a = xy (sqr (x a)) (sqr (y a))
mp1, mp2 :: Point (Moving P.Float)
mp1 = xy (\t -> 4.0 + (0.5 * t)) (\t -> 4.0 - (0.5 * t))
mp2 = xy (\t -> 0.0 + (1.0 * t)) (\t -> 0.0 - (1.0 * t))
movingDist_1_2 = dist mp1 mp2
dist_at_2 = movingDist_1_2 2.0
I need help with this function. It has to return 2 lists. All the points, that are in the radius in the first and all others in the second. This is what I wrote, but it gave me so much errors.
type Point = (Double, Double)
splitPoints :: Point -> Double -> [Point] -> ([Point], [Point])
splitPoints (x, y) r (z:zs)
|(_, _) _ [] = ([][])
|x * x + y * y <= r * r = (x,y) : (splitPoints (x, y) r zs) []
|otherwise = [] (x,y) : (splitPoints (x, y) r zs)
First, you have to move the pattern match for the empty list out of the guard and as a seperate function clause.
Second, I suggest putting the recursive call in a where clause to seperate the points in the circle and outside of the circle. Then you can check in your guard, in which list you have to insert the point.
type Point = (Double, Double)
splitPoints :: Point -> Double -> [Point] -> ([Point], [Point])
splitPoints _ _ [] = ([], [])
splitPoints center#(centerx, centery) r ((x,y):zs)
| (x-centerx)**2 + (y-centery)**2 <= r**2 = ((x,y) : inside, outside)
| otherwise = (inside, (x,y) : outside)
where (inside, outside) = splitPoints center r zs
The reason this does not work is because you make some syntactical errors:
pattern matching in the guards;
([][]) is not a 2-tuple with two empty lists;
[] (x, y) will try to perform function application with [] the function.
You furthermore calculate the distance of the center point to the origin, not the distance between two points. So either all Points will be in the left sublist, or in the right sublist.
We can fix this with:
type Point = (Double, Double)
splitPoints :: Point -> Double -> [Point] -> ([Point], [Point])
splitPoints _ _ [] = ([], [])
splitPoints (x0, y0) r ((x, y):zs)
| dx*dx + dy*dy <= r*r = ((x, y):ra, rb)
|otherwise = (ra, (x, y):rb)
where dx = x - x0
dy = y - y0
(ra,rb) = splitPoints (x0, y0) r zs
But this still does not look very elegant. I think it is probably better to separte your concerns. You can for example use partition :: (a -> Bool) -> [a] -> ([a], [a]) to divide items in two lists: one that satisfies a predicate, and one where the items do not satisfy this predicate.
So now it is a matter of designing a predicate. We can do that with:
import Data.List(partition)
type Point = (Double, Double)
splitPoints :: Point -> Double -> [Point] -> ([Point], [Point])
splitPoints (x0, y0) r = partition p
where p (x, y) = dx*dx + dy*dy <= r * r
where dx = x - x0
dy = y - y0
I want to realize power function for my custom data type. I mean power (^) which has following signature:
(^) :: (Num a, Integral b) => a -> b -> a
And I mean that my data type MyData should be instance of Num, so I could write
x :: MyData
...
y = x ^ b
where b is some Integral. It's very easy when we need function of one class like
(+), (-), (*) :: (Num a) => a -> a -> a
We just write
instance Num MyData where
(*) x y = someFunc x y
But I have no idea how to define it taking into account that there is also Integral b. That syntax should be like
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
But I've tried a hundred of such variations and nothing works. Hours of googling also didn't help.
You don't have to do anything to define (^) for your data type; if your type has a Num instance, you get x ^ b for free, because (^) is defined for any type with a Num instance. (It basically just calls * a lot.)
Note that (^) is not a member of Num or Integral; it's just a standalone function whose type is constrained by both classes.
From https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
x0 is your MyData value; the only thing (^) ever does with x0 (by virtue of it being passed as the x argument to f or g) is to multiply it by itself, so technically (^) will work as long as you have defined (*) in your Num instance.
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 am trying to implement the law of cosines function, and here is my code:
cosC :: [a] -> a
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where x = head(tail(tail(sides)))
y = head(tail(sides))
z = head(sides)
But I get two errors:
No instance for (Fractional a)
arising from a use of `/'
In the expression: (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
In an equation for `cosC':
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where
x = head (tail (tail (sides)))
y = head (tail (sides))
z = head (sides)
and
No instance for (Num a)
arising from the literal `2'
In the first argument of `(*)', namely `2'
In the first argument of `(*)', namely `2 * x'
In the second argument of `(/)', namely `(2 * x * y)'
Edit: I have fixed the sign typo in the law of cosines above. Thanks to Daniel Fischer for pointing that out.
You're trying to calculate numerical results out of general types a, that can't possibly work. (It's like trying to build a bridge not just for general road-vehicles but for general things, e.g. spaceships, skyscrapers, paper clips and neutron stars). Just add the Floating constraint to a:
cosC :: Floating a => [a] -> a
and you can perform any of the arithmetic operations you need for such a calculation. (Fractional is actually enough for this function, but you won't be able to calculate the arccos of the result then).
Unrelated to your problem, note that there's a much better way to decompose lists in Haskell:
cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0
is equivalent to your definition. Why are you taking the arguments as a list anyway? That's quite a Lisp-ish thing to do, in Haskell I'd prefer
cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)
cosC :: Fractional a => [a] -> a
And this is how you can find out (in ghci):
*Main> let fun [x, y, z] = (x * x + y * y + z * z) / (2 * x * y)
*Main> :type fun
fun :: Fractional a => [a] -> a