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

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.

Related

QuickCheck Arbitrary instance for abstract data type with smart constructor

I am new to the language, trying to write my first non-trivial program. On the way, I am stuck creating an Arbitrary instance. Yet, I suppose my question to follow points at my general lack of understanding composing several applicative and monadic types. Hence, I hope to gain fundamental insight form the following. Thanks for your help!
I defined an Address type and a smart constructor with validation of the individual fields as follows:
data Address = Address
{ street :: StreetName
, streetExt :: Maybe StreetName
, city :: CityName
, zipCode :: ZipCode
, country :: CC.CountryCode
} deriving (Eq, Show)
mkAddress :: Text -> Maybe Text -> Text -> Text -> Text -> Maybe Address
mkAddress aStreet aStreetExt aCity aZipCode aCountry =
Address <$> mkStreetName aStreet
<*> Just (aStreetExt >>= mkStreetName)
<*> mkCityName aCity
<*> mkZipCode aZipCode
<*> CC.fromMText aCountry
StreetName, CityName and ZipCode are newtype wrappers for Text with a validating smart constructor that simply limits the maximum length of these fields. The streetExt field is optional. The country code uses Data.ContryCodes.CountryCode.
The overall type is abstract, the defining module only exports the smart constructor but not the data constructor.
I am now trying to create an Arbitrary instance for this type>
instance Arbitrary D.Address where
arbitrary = do
maybeAddress <- D.mkAddress <$> arbitrary -- streetName
<*> return Nothing -- streetExt
<*> arbitrary -- city
<*> arbitrary -- zipCode
<*> elements ["DE", "FR", "AG", "RW"] -- country
return fromJust maybeAddress
However, I am stuck with the following type checker error:
• Couldn't match type ‘Maybe a0 -> a0’ with ‘Gen D.Address’
Expected type: Maybe D.Address -> Gen D.Address
Actual type: Maybe D.Address -> Maybe a0 -> a0
• The function ‘return’ is applied to two arguments,
but its type ‘(Maybe a0 -> a0)
-> Maybe D.Address -> Maybe a0 -> a0’
has only three
From this error, I take that there is some issue wrapping the Generator inside the Maybe, or the other way around. But even after several experiments lift and join I can't get it to type check. Thus, I suspect that my mental model is flawed of how the types are wrapped and how the generator monads are returned.
It would be great if someone could point out my mistake.
In addition, I would highly appreciate a comment on this type of data modelling with abstract types and smart constructors - is this general recommended practice, or does it lead to problems like the one I am facing?
Thanks very much!
The error message says it (although the subsequent explanation is misleading):
The function ‘return’ is applied to two arguments
You have
return fromJust maybeAddress
You want
return (fromJust maybeAddress)

Datatype Person mother from mother (grandmother)

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.

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].

What's the recommended way of handling complexly composed POD(plain-old-data in OO) in Haskell?

I'm a Haskell newbie.
In statically typed OO languages (for instance, Java), all complex data structures are presented as class and instances. An object can have many attributes (fields). And another object can be a value of the field. Those fields can be accessed with their names, and statically typed by class. Finally, those objects construct huge graph of object which linked each other. Most program uses data graph like this.
How can I archive these functionality in Haskell?
If you really do have data without behavior, this maps nicely to a Haskell record:
data Person = Person { name :: String
, address :: String }
deriving (Eq, Read, Show)
data Department = Management | Accounting | IT | Programming
deriving (Eq, Read, Show)
data Employee = Employee { identity :: Person
, idNumber :: Int
, department :: Department }
| Contractor { identity :: Person
, company :: String }
deriving (Eq, Read, Show)
This says that a Person is a Person who has a name and address (both Strings); a Department is either Management, Accounting, IT, or Programming; and an Employee is either an Employee who has an identity (a Person), an idNumber (an Int), and a department (a Department), or is a Contractor who has an identity (a Person) and a company (a String). The deriving (Eq, Read, Show) lines enable you to compare these objects for equality, read them in, and convert them to strings.
In general, a Haskell data type is a combination of unions (also called sums) and tuples (also called products).1 The |s denote choice (a union): an Employee is either an Employee or a Contractor, a Department is one of four things, etc. In general, tuples are written something like the following:
data Process = Process String Int
This says that Process (in addition to being a type name) is a data constructor with type String -> Int -> Process. Thus, for instance, Process "init" 1, or Process "ls" 57300. A Process has to have both a String and an Int to exist. The record notation used above is just syntactic sugar for these products; I could also have written data Person = Person String String, and then defined
name :: Person -> String
name (Person n _) = n
address :: Person -> String
address (Person _ a) = a
Record notation, however, can be nice for complex data structures.
Also note that you can parametrize a Haskell type over other types; for instance, a three-dimensional point could be data Point3 a = Point3 a a a. This means that Point3 :: a -> a -> a -> Point3 a, so that one could write Point3 (3 :: Int) (4 :: Int) (5 :: Int) to get a Point3 Int, or Point3 (1.1 :: Double) (2.2 :: Double) (3.3 :: Double) to get a Point3 Double. (Or Point3 1 2 3 to get a Num a => Point3 a, if you've seen type classes and overloaded numeric literals.)
This is what you need to represent a data graph. However, take note: one problem for people transitioning from imperative languages to functional ones—or, really, between any two different paradigms (C to Python, Prolog to Ruby, Erlang to Java, whatever)—is to continue to try to solve problems the old way. The solution you're trying to model may not be constructed in a way amenable to easy functional programming techniques, even if the problem is. For instance, in Haskell, thinking about types is very important, in a way that's different from, say, Java. At the same time, implementing behaviors for those types is done very differently: higher-order functions capture some of the abstractions you've seen in Java, but also some which aren't easily expressible (map :: (a -> b) -> [a] -> [b], filter :: (a -> Bool) -> [a] -> [a], and foldr :: (a -> b -> b) -> b -> [a] -> b come to mind). So keep your options open, and consider addressing your problems in a functional way. Of course, maybe you are, in which case, full steam ahead. But do keep this in mind as you explore a new language. And have fun :-)
1: And recursion: you can represent a binary tree, for instance, with data Tree a = Leaf a | Branch a (Tree a) (Tree a).
Haskell has algebraic data types, which can describe structures or unions of structures such that something of a given type can hold one of a number of different sets of fields. These fields can set and accessed both positionally or via names with record syntax.
See here: http://learnyouahaskell.com/making-our-own-types-and-typeclasses

Resources