case class Point(x: Int, y: Int)
data Point = Point { x :: Int
, y :: Int
}
If you need your datatype to be visible outside of the file, in which it's defined, then remember to export it:
module YourModule ( Point(Point) )
case class Point(x: Int, y: Int)
-- this needs to be at the top of a file
{-# LANGUAGE DeriveGeneric #-}
data Point = Point { x :: Int
, y :: Int
} deriving (Eq, Generic Show)
Eq
- with instance of that typeclass (Point 1 1) == (Point 123 321)
will compile.Generic
- you can think of it as kind of shapeless.LabelledGeneric
- something that is a base for other typeclass derivation mechanisms. For example aeson (JSON library) can generate codecs for your data type providing it has an instance of Generic
. I know it sounds vague but my current understanding is vague too.Show
- with instance of that typeclass you can show (Point 1 1)
which returns a string. We can compare it to toString
mechanism known from JVM world.{-# LANGUAGE DeriveGeneric #-}
if you don't want to derive Generic
- you would still be able to derive e.g. Show
.
Point(3, 15)
Point 3 15
Point(3, 15).x
x (Point 3 5)
It will work only if you exported `x` and imported it to scope where you use it. You can export field accessors with:
module YourModule ( Point(Point, x, y) ) where ...
Point(3, 15).copy(y = 100)
(Point 3 15) { y = 100 }
sealed trait Colour
case object Black extends Colour
case object Grey extends Colour
case object Grey extends Colour
data Colour = Black
| Grey
| White
In order to be able to use data constructors you need to export them with:
module YourModule ( Colour(Black, Grey, White) ) where ...
sealed trait ClientError
case class ParsingError(input: String, msg: String)
case class HostUnavailable(host: String)
case object OtherError
data ClientError = ParsingError { input :: String, msg :: String }
| HostUnavailable { host :: String }
| OtherError