KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
Suppose that I have two data types Foo and Bar. Foo has fields x and y. Bar has fields x and z. I want to be able to write a function that takes either a Foo or a Bar as a parameter, extracts the x value, performs some calculation on it, and then returns a new Foo or Bar with the x value set accordingly. Here is one approach: class HasX a where getX :: a -> Int setX :: a -> Int -> a data Foo = Foo Int Int deriving Show instance HasX Foo where getX (Foo x _) = x setX (Foo _ y) val = Foo val y getY (Foo _ z) = z setY (Foo x _) val = Foo x val data Bar = Bar Int Int deriving Show instance HasX Bar where getX (Bar x _) = x setX (Bar _ z) val = Bar val z getZ (Bar _ z) = z setZ (Bar x _) val = Bar x val modifyX :: (HasX a) => a -> a modifyX hasX = setX hasX $ getX hasX + 5 The problem is that all those getters and setters are painful to write, especially if I replace Foo and Bar with real-world data types that have lots of fields. Haskell's record syntax gives a much nicer way of defining these records. But, if I try to define the records like this data Foo = Foo {x :: Int, y :: Int} deriving Show data Bar = Foo {x :: Int, z :: Int} deriving Show I'll get an error saying that x is defined multiple times. And, I'm not seeing any way to make these part of a type class so that I can pass them to modifyX. Is there a nice clean way of solving this problem, or am I stuck with defining my own getters and setters? Put another way, is there a way of connecting the functions created by record syntax up with type classes (both the getters and setters)? EDIT Here's the real problem I'm trying to solve. I'm writing a series of related programs that all use System.Console.GetOpt to parse their command-line options. There will be a lot of command-line options that are common across these programs, but some of the programs m
Tags (comma-separated)
Save Edits
Cancel