Datatype Person mother from mother (grandmother) - haskell

Imagine I've got a datatype Person.
data Person = Person String Person
The 2. Person should be the mother.
showGrandmother :: Person -> Maybe Person
showGrandmother (Person _ mother) = Just mother
Will only show the mother from person x.
How can I show the grandmother?

first, your data definition is missing the base case. Assuming this represents matrilineality, I would start with Eve as the base case
data Person = Eve | Person String Person deriving (Show)
defining mother function
mother Eve = Nothing
mother (Person _ m) = Just m
now grandmother is applying this twice
grandmother = \x -> mother x >>= mother
With Control.Monad Kleiski operators, this can be written much nicely
grandmother = mother >=> mother

With pattern matching, you aren't limited to one level of constructors, you can nest them to go further "in":
showGrandmother :: Person -> Maybe Person
showGrandmother (Person _ (Person _ grandmother)) = Just grandmother
As a sidenote, I'm not a Haskell expert, but it seems like the data type is a bit circular for what is meant to be a model of a family tree. You can't actually create a person without it referencing another person. Maybe something better would be...
data Person = Person String (Maybe Person)
... in which case, finding the grandmother can be done as...
showGrandmother :: Person -> Maybe Person
showGrandmother (Person _ Just (Person _ (Just grandmother)))) = Just grandmother
showGrandmother _ = Nothing
... making sure to handle the base case when someone doesn't have a grandmother. Your original type didn't need to handle this case because everyone must have a grandmother according to it.
And taking inspiration from the #Karafka's answer, it's possible to factor out finding the mother of a person...
showMother :: Person -> Maybe Person
showMother (Person _ (Just mother)) = Just mother
showMother _ = Nothing
... and using the fact that Maybe is a monad, can use it as below.
showGrandmother :: Person -> Maybe Person
showGrandmother x = showMother x >>= showMother
I suspect understanding the above monadic code would be out of scope for this particular question.

Related

Manipulating a value within several layers of monads

My goal is to pull out numVal4 from Employment -- but doing it from the level of the MyEmployment value.
data Employment = Employment
{ textVal1 :: Text
, textVal2 :: Text
, textVal3 :: Text
, numVal4 :: Money }
data MyEmployment = MyEmployment Person Employment
MyEmployment (Person "Me") (Employment "This" "is a" "test" 55)
fmap . fmap (fromInteger (Employment _ _ _ x)) MyEmployment
EDIT:
I should have bee more specific. I need to access the value from within a DMap. The actual code looks like something closer to this:
thing = dmap ! (Some_Function . Some_OtherFunction $ MyEmployment)
And I need to get the numeric value from inside of Employment, with some kind of wrapper like:
thing = fmap (fromIntegral (Employment _ _ _ x)) (dmap ! (Some_Function . Some_OtherFunction $ MyEmployment)
Apart from all the syntax issues, I think what you are trying to do is the following.
This is how you declare a data type:
data Employment = Employment
{ textVal1 :: Text
, textVal2 :: Text
, textVal3 :: Text
, numVal4 :: Money }
Note the ::s which are not =, and note the indentation.
MyEmployment seems to be a data type and by MyEmployment :: Person Employment I think you in fact mean
data MyEmployment = MyEmployment Person Employment
In this setting then, If you want to take a value of type MyEmployment, and apply a function to the numVal4 field of the Employment field, record syntax allows you to write:
foo :: (Money -> Money) -> MyEmployment -> MyEmployment
foo f (MyEmployment p e#(Employment {numVal4 = nv}))
= MyEmployment p ( e {numVal4 = f nv})

Haskell - Implementing function which extracts values from an algebraic data type

Okay, as someone who came from Object-Oriented programming not a week ago, Haskell is somewhat overwhelming - its likely that this has been answered, but all my research has been fruitless. Please bear with me.
Say that I have two algebraic data types:
data Person = Person {name :: String, houseNumber :: Integer, hasBorrowed :: Bool}
data Book = Book {borrower :: Person, title :: String}
Now, I know that you can simply extract a value from a single algebraic data type with a function:
getHouseNumber :: Person -> Integer
getHouseNumber (Person _ houseNumber _) = houseNumber
getBorrower :: Book -> Person
getBorrower (Book borrower _) = borrower
My question is (and I swear I'm going to smack myself in the head when I get the answer) how would I write a function which extracts houseNumber (as an example) straight from book? In other words:
getHouseNumberFromBook :: Book -> Integer
Thanks in advance.
First, this is redundant
getHouseNumber :: Person -> Integer
getHouseNumber (Person _ houseNumber _) = houseNumber
since houseNumber is already defined automatically as a similar projection. We get this from using the record notation in the data declaration. That is, Haskell already automatically defines
houseNumber :: Person -> Integer
houseNumber (Person _ hN _) = hN
and there's no need to duplicate that. Similarly for borrower and other fields.
About the actual question, we can simply compose the accessors:
getHouseNumberFromBook :: Book -> Integer
getHouseNumberFromBook b = houseNumber (borrower b)
or, more idiomatically,
getHouseNumberFromBook :: Book -> Integer
getHouseNumberFromBook = houseNumber . borrower
This is so short that one can probably use its definition directly, without having to define a custom function.
The fields of records are actually functions that extract a value from an ADT. So you have borrower :: Book -> Person and houseNumber :: Person -> Integer. Therefor you can use the composition operator . to create a new function houseNumber . borrower :: Book -> Integer.

Writing an OOP-style "setter" function in Haskell using record-syntax

I'm reading a tutorial on lenses and, in the introduction, the author motivates the lens concept by showing a few examples of how we might implement OOP-style "setter"/"getter" using standard Haskell. I'm confused by the following example.
Let's say we define a User algebraic data types as per Figure 1 (below). The tutorial states (correctly) that we can implement "setter" functionality via the NaiveLens data type and the nameLens function (also in Figure 1). An example usage is given in Figure 2.
I'm perplexed as to why we need such an elaborate construct (i.e., a NaiveLens datatype and a nameLens function) in order to implement "setter" functionality, when the following (somewhat obvious) function seems to do the job equally well: set' a s = s {name = a}.
HOWEVER, given that my "obvious" function is none other than the lambda function that's part of nameLens, I suspect there is indeed an advantage to using the construct below but that I'm too dense to see what that advantage is. Am hoping one of the Haskell wizards can help me understand.
Figure 1 (definitions):
data User = User { name :: String
, age :: Int
} deriving Show
data NaiveLens s a = NaiveLens { view :: s -> a
, set :: a -> s -> s
}
nameLens :: NaiveLens User String
nameLens = NaiveLens name (\a s -> s {name = a})
Figure 2 (example usage):
λ: let john = User {name="John",age=30}
john :: User
λ: set nameLens "Bob" john
User {name = "Bob", age = 30}
it :: User
The main advantage of lenses is that they compose, so they can be used for accessing and updating fields in nested records. Writing this sort of nested update manually using record update syntax gets tedious quite quickly.
Say you added an Email data type:
data Email = Email
{ _handle :: String
, _domain :: String
} deriving (Eq, Show)
handle :: NaiveLens Email String
handle = NaiveLens _handle (\h e -> e { _handle = h })
And added this as a field to your User type:
data User = User
{ _name :: String
, _age :: Int
, _userEmail :: Email
} deriving (Eq, Show)
email :: NaiveLens User Email
email = NaiveLens _userEmail (\e u -> u { _userEmail = e })
The real power of lenses comes from being able to compose them, but this is a bit of a tricky step. We would like some function that looks like
(...) :: NaiveLens s b -> NaiveLens b a -> NaiveLens s a
NaiveLens viewA setA ... NaiveLens viewB setB
= NaiveLens (viewB . viewA) (\c a -> setA (setB c (viewA a)) a)
For an explanation of how this was written, I'll defer to this post, where I shamelessly lifted it from. The resulting set field of this new lens can be thought of as taking a new value and a top-level record, looking up the lower record and setting its value to c, then setting that new record for the top-level record.
Now we have a convenient function for composing our lenses:
> let bob = User "Bob" 30 (Email "bob" "gmail")
> view (email...handle) bob
"bob"
> set (email...handle) "NOTBOB" bob
User {_name = "Bob", _age = 30, _userEmail = Email {_handle = "NOTBOB", _domain = "gmail"}}
I've used ... as the composition operator here because I think it's rather easy to type and still is similar to the . operator. This now gives us a way to drill down into a structure, getting and setting values fairly arbitrarily. If we had a domain lens written similarly, we could get and set that value in much the same way. This is what makes it look like it's OOP member access, even when it's simply fancy function composition.
If you look at the lens library (my choice for lenses), you get some nice tools to automatically build the lenses for you using template haskell, and there's some extra stuff going on behind the scenes that lets you use the normal function composition operator . instead of a custom one.

Haskell: Create a list of only certain "kind" of type?

I've been working through both Learn You a Haskell and Beginning Haskell and have come on an interesting problem. To preface, I'm normally a C++ programmer, so forgive me if I have no idea what I'm talking about.
One of the exercises in Beginning Haskell has me create a type Client, which can be a Government organization, Company, or Individual. I decided to try out record syntax for this.
data Client = GovOrg { name :: String }
| Company { name :: String,
id :: Integer,
contact :: String,
position :: String
}
| Individual { fullName :: Person,
offers :: Bool
}
deriving Show
data Person = Person { firstName :: String,
lastName :: String,
gender :: Gender
}
deriving Show
data Gender = Male | Female | Unknown
deriving Show
This is used for an exercise where given a list of Clients, I have to find how many of each gender are in the list. I started by filtering to get a list of just Individuals since only they have the Gender type, but my method seems to be completely wrong:
listIndividuals :: [Client] -> [Client]
listIndividuals xs = filter (\x -> x == Individual) xs
How would I get this functionality where I can check what "kind" of Client something is. Also for the record syntax, how is my coding style? Too inconsistent?
First of all, I would recommend not using record types with algebraic types, because you end up with partial accessor functions. For example, it is perfectly legal to have the code position (Individual (Person "John" "Doe" Male) True), but it will throw a runtime error. Instead, consider something more like
data GovClient = GovClient {
govName :: String
} deriving Show
data CompanyClient = CompanyClient {
companyName :: String,
companyID :: Integer, -- Also, don't overwrite existing names, `id` is built-in function
companyContact :: String,
companyPosition :: String
} deriving Show
data IndividualClient = IndividualClient {
indvFullName :: Person,
indvOffers :: Bool
} deriving Show
Then you can have
data Client
= GovOrg GovClient
| Company CompanyClient
| Individual IndividualClient
deriving (Show)
Now you can also define your function as
isIndividualClient :: Client -> Bool
isIndividualClient (Individual _) = True
isIndividualClient _ = False
listIndividuals :: [Client] -> [IndividualClient]
listIndividuals clients = filter isIndividualClient clients
Or the more point-free form of
listIndividuals = filter isIndividualClient
Here, in order to make the decision I've simply used pattern matching in a separate function to determine which of Client's constructors was used. Now you get the full power of record and algebraic types, with just a hair more code to worry about, but a lot more safety. You'll never accidentally call a function expecting a government client on an individual client, for example, because it wouldn't type check, whereas with your current implementation it would be more than possible.
If you're concerned with the longer names, I would recommend eventually looking into the lens library that is designed to help you manipulate complex trees of record types with relative ease.
With your current implementation, you could also do something pretty similar to the final solution:
isIndividualClient :: Client -> Bool
isIndividualClient (Individual _ _) = True
isIndividualClient _ = False
listIndividuals :: [Client] -> [Client]
listIndividuals clients = filter isIndividualClient clients
The main difference here is that Individual takes two fields, so I have two _ wildcard matches in the pattern, and the type of listIndividuals is now [Client] -> [Client].

Haskell: How to put multiple instances in the same module?

Let's say that I have the following code:
import Data.List.Ordered
data Person = Person String String
deriving (Show, Eq)
main :: IO ()
main = print . show . sort $ [(Person "Isaac" "Newton"), (Person "Johannes" "Kepler")]
And in the same module, I want to be able to sort the list by both first name and by last name. Obviously I can't do this:
instance Ord Person where
compare (Person _ xLast) (Person _ yLast) = compare xLast yLast
instance Ord Person where
compare (Person xFirst _) (Person yFirst _) = compare xFirst yFirst
So, what are my options?
This page mentions "You can achieve this by wrapping the type in a newtype and lift all required instances to that new type." Can someone give an example of that?
Is there a better way?
The newtype method would be:
newtype ByFirstname = ByFirstname { unByFirstname :: Person }
instance Ord ByFirstname where
-- pattern matching on (ByFirstname (Person xFirst _)) etc
compare [...] = [...]
newtype ByLastname = ByLastname { unByLastname :: Person }
instance Ord ByLastname where
-- as above
Then the sorting function would be something like:
sortFirstname = map unByFirstname . sort . map ByFirstname
and similarly for ByLastname.
A better way is to use sortBy, compare and on, with functions for retrieving the first and last names. i.e.
sortFirstname = sortBy (compare `on` firstName)
(On that note, it might be worth using a record type for Person, i.e. data Person = Person { firstName :: String, lastName :: String }, and one even gets the accessor functions for free.)
You don't want to define multiple Ord instances just to sort by different orders. You just need to use the sortBy function, which takes an explicit comparison function as its argument.
Neat trick: if you use record types to define your Person type, import Data.Function (which gives you the on function) and Data.Monoid, you can use some neat tricks to make this much briefer and easy:
import Data.Function (on)
import Data.Monoid (mappend)
import Data.List (sortBy)
data Person = Person { firstName :: String, lastName :: String }
instance Show Person where
show p = firstName p ++ " " ++ lastName p
exampleData = [ Person "Mary" "Smith"
, Person "Joe" "Smith"
, Person "Anuq" "Katig"
, Person "Estanislao" "Martínez"
, Person "Barack" "Obama" ]
--
-- The "on" function allows you to construct comparison functions out of field
-- accessors:
--
-- compare `on` firstName :: Person -> Person -> Ordering
--
-- That expression evaluates to something equivalent to this:
--
-- (\x y -> compare (firstName x) (firstName y))
--
sortedByFirstName = sortBy (compare `on` firstName) exampleData
sortedByLastName = sortBy (compare `on` lastName) exampleData
--
-- The "mappend" function allows you to combine comparison functions into a
-- composite one. In this one, the comparison function sorts first by lastName,
-- then by firstName:
--
sortedByLastNameThenFirstName = sortBy lastNameFirstName exampleData
where lastNameFirstName =
(compare `on` lastName) `mappend` (compare `on` firstName)
The reason that page mentions newtype is that you cannot have two instances of the same class for a given type. Well, you can but not in the same scope and it's generally a really bad idea. See Orphan Instances for more information (as C. A. McCann pointed out this isn't about orphan instances. I included the link because it has a good description of why duplicate instances, even in cases that superficially work, is a bad idea.).
An example of newtype would be:
newtype SortFirst = SF Person
instance Ord Person where
compare (Person _ xLast) (Person _ yLast) = compare xLast yLast
instance Ord SortFirst where
compare (SF (Person xFirst _)) (SF (Person yFirst _)) = compare xFirst yFirst
Then when you want to sort by first name you would have to do:
sort (map SF persons)
It's not very convenient so it may be better to use sortBy which takes an comparison function as an argument.
It seems that all the functions in Data.List.Ordered have "by" variants that let you provide a comparison function rather than using an Ord instance. If there's no single obvious "standard" ordering, that's not a bad option.
It then becomes your responsibility to ensure any given list is always used with a consistent comparison function, however, which is a potential source of all kinds of fun bugs.
If I needed to work with many ordered lists using a variety of orderings, rather than fussing with newtype wrapping and unwrapping--which is dreadfully tedious--I'd consider a data type to bundle a list with its comparison function, then define proxy functions that use the "by" functions with the associated comparison.

Resources