Reputation: 874
Im trying to define a function which I want to behave slightly differently depending on what datatype is passed in as the argument, strings and integers. How would one go about doing this? Or are there any changes you could suggest to somehow compose these two into one function. Ive read that trying to validate the datatype is not very haskell like so I thought overriding might be the way to go to do this but the compiler doesnt like the duplicate :(
jumpTo :: Int -> [String] -> [String]
jumpTo index t = do
let (x,y) = splitAt index t
init x ++ [last x ++ "QQ"] ++ y
jumpTo :: String -> [String] -> [String]
jumpTo string t = do
pos <- [fromJust (findWord string t)]
let (x,y) = splitAt pos a
init x ++ [last x ++ "QQ"] ++ y
In words, I want a function jumpTo
which can either be passed a String
or Int
as its first argument; if its a string, I find it in the list, and for an integer I do the operations with the index straight away. It just seems more elegant to have the same function doing this.
Upvotes: 1
Views: 302
Reputation: 80744
This is exactly the idea behind type classes: you define your function (or a group of functions) not by itself, but as belonging to a type class, which is tagged with a type variable (or several). Then you define one or more instances of the type class with different types substituted for that type variable, and you define separate bodies for the function in each instance. The end effect is that the function has different body depending on the types of its arguments or result.
In your example:
class JumpTo a where
jumpTo :: a -> [String] -> [String]
instance JumpTo Int where
jumpTo index t = do
let (x,y) = splitAt index t
init x ++ [last x ++ "QQ"] ++ y
instance JumpTo String where
jumpTo string t = do
pos <- [fromJust (findWord string t)]
let (x,y) = splitAt pos a
init x ++ [last x ++ "QQ"] ++ y
Upvotes: 5