Hi everyone! I am new here and a beginning Haskeller.
I have a question. I am writing an app and a few days ago I asked a question on stackoverflow. The commenters suggested that my approach, based on the experience with java, is not a very functional style. and as a beginner, I should not define my typeclasses.
In the light of making my style more functional, I want to ask about certain part of the code I am trying to write.
Currently I defined two types of curves on 2D plane
-- Y = slope * X +constant
data LinearCurve = LinearCurve {slope::Double,constant :: Double}
data Point = Point {x::Double,y::Double}
-- piece wise linear curve that connects given points
newtype PieceWiseLinearCurve = DataCurve{points :: [XYPoint]}
data CoordType = X | Y
type Err = String
Later, other types of curves could be added.
What I need is an interpolating function for all different types of curves.
interpolate :: a -> CoordType -> Double -> Either Err Double
My approached based on my past java experience would be to create typeclass and then make instance for every type that I want to have ability to interpolate. But now it seems to me, that even this wording is more OOP than functional - having data types ability to do something is pretty OOP way of thinking I guess…
Anyway, If I forbid myself to define typeclasses I can define new type
newtype Interpolator = Interpolator (CoordType -> Double -> Either Err Double)
and bunch of functions that give me this Interpolator based on the data. I guess, it would be better to combine all curves into one type
data Curve = LinC LinearCurve
| PieceLinC PieceWiseLinearCurve
and write one function
getInterpolatorFromCurve :: Curve -> Interpolator
But of course, many different things can be used to get Interpolator. For example, I can write
getInterpolatorFromPoints :: (XYPoint, XYPoint) -> Interpolator
I can also go to higher dimensions, in which case I need to redefine interpolator
data Interpolator a b = Interpolator (b -> a -> Either Err Double),
where b should be appropriate coordtype for given dimension. Ok, I have my interpolator type, that can be reused in many different contexts, but I need to spam my namespace by many functions of type getInterpolatorFrom???.
Wouldn’t it better to just use type class with one function that gives me the interpolator and have only one name for the task?
The problem is, I do not see why I should not use typeclasses this way. I understand that my only motive is to reduce number of function names I have instead of the more noble motive to implement polymorphic functions later on (like I can do using Num class to write sum function that sums numbers in a list without knowing the actual number type it will be used for). But why is it considered bad style? What is the motive behind it?
Or is there some other, solution I am not seeing?