Let's say I have the following datatype
data A = A{x::Int,y::Int,z::Int}
Is there a way to apply 0 on all the fields to get something like this :
let a = A 0 0 0
Basically not repeating 0
The goal at the end would be to use mempty from Sum Int and do something like this :
let a = myfunction mempty :: Sum Int
and Have a == A 0 0 0
Thanks !
When you define the database fields, you select a data type for each field. The data type tells Content Manager OnDemand what kind of data can be stored in the field. For search fields, in which users enter values to construct queries For display fields, to identify the items in the document list
Data can also be constant or variable within programs and functions. In a program, data values can be constant or variable. If values are variable they can be changed by the program and the user. When a program is run, the data values are held in memory whilst they are being worked on.
The following example declares the Public constant conAge as an Integer and assigns it the value 34. Constants can be declared as one of the following data types: Boolean, Byte, Integer, Long, Currency, Single, Double, Date, String, or Variant.
Public Const conAge As Integer = 34 Constants can be declared as one of the following data types: Boolean, Byte, Integer, Long, Currency, Single, Double, Date, String, or Variant. Because you already know the value of a constant, you can specify the data type in a Const statement. You can declare several constants in one statement.
There isn't one function, but you can compose Control.Monad.join with itself. You also have to unpack the 0 from mempty first, since it has type Sum Int, not Int.
let a = (join . join) A (getSum mempty)
You could then define myfunction has
myfunction = (join . join) A . getSum
and write
let a = myfunction (mempty :: Sum Int)
The more direct definition of myfunction, though, would simply be
myfunction (Sum x) = A x x x
Since coincidentally Data.Default defines 0 as the default value for Int, you can use data-default-class to derive it generically with DeriveAnyClass:
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
import Data.Default (Default(..))
import GHC.Generics (Generic(..))
data A = A { x, y, z :: Int }
deriving (Default, Generic)
-- (def :: A) == A 0 0 0
You can make this more explicit with DerivingStrategies and enforce it with -Wmissing-deriving-strategies:
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# OPTIONS_GHC -Wmissing-deriving-strategies #-}
import Data.Default (Default(..))
import GHC.Generics (Generic(..))
data A = A { x, y, z :: Int }
deriving (Default, Generic)
deriving anyclass (Default)
deriving stock (Generic)
-- (def :: A) == A 0 0 0
However, Data.Default is a class with no laws; it’s better used to indicate the canonical default value of a more complex configuration-like type, because its choices for primitive types are essentially arbitrary.
So if you are able to change the type a bit, you can alternatively use the generic-deriving package, in one of two ways. First, by using Sum Int as the type of the fields and deriving Semigroup and Monoid instances with generics:
{-# LANGUAGE DeriveGeneric #-}
import Generics.Deriving.Monoid
data A = A { x, y, z :: Sum Int }
deriving (Generic)
instance Monoid A where mempty = memptydefault
instance Semigroup A where (<>) = sappenddefault
-- (mempty :: A) == A 0 0 0
-- A 1 2 3 <> A 4 5 6 == A 5 7 9
Or second—and this is my preference—by replacing the data type with a newtype over a tuple of Ints, and using DerivingVia to derive the instance via Sum Int:
{-# LANGUAGE DerivingVia #-}
newtype A = A (Int, Int, Int)
deriving (Monoid, Semigroup) via (Sum Int, Sum Int, Sum Int)
-- (mempty :: A) == A 0 0 0
-- A 1 2 3 <> A 4 5 6 == A 5 7 9
You can recover the field names using lenses (e.g. x is _1) or by writing getters and setters manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With