Haskell--Manipulating data within a tuple - haskell

I'm attempting to simulate a checkers game using haskell. I am given a 4-tuple named, checkersState, that I would like to manipulate with a few different functions. So far, I have a function, oneMove, that receives input from checkerState and should return a tuple of the modified data:
The Input Tuple:
(
3600,
"",
[
"----------",
"------r---",
"----------",
"----------",
"---r-r----",
"------r---",
"---w---w-w",
"----------",
"----------",
"------w---"
],
(
49
,
43
)
)
So far I have something similar to below defining my function but am unsure how to access the individual members within the tuple checkerState. This method will take a time, array of captured pieces, board, and move to make, and return a time, array of captured pieces, and board. Currently, I would like to modify the time (INT) in the tuple depending on the state of the board:
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
Thanks in advance!

You can use pattern-matching to pull out the elements, do whatever changes need to be made, and pack them back into a tuple. For example, if you wanted to increment the first value, you could:
onemove (a,b,c,d) = (a + 1,b,c,d)
If you find yourself doing this a lot, you might reconsider using a tuple and instead use a data type:
data CheckersState = CheckersState { time :: Int -- field names are just
, steps :: [Char] -- guesses; change them
, board :: [[Char]] -- to something that
, pos :: (Int, Int) -- makes sense
} deriving (Eq, Read, Show)
Then you can update it with a much more convenient syntax:
onemove state = state { time = time state + 1 }
If you want to stick with tuples and you happen to be using lenses, there’s another easy way to update your tuple:
onemove = over _1 (+1)
Or if you’re using lenses and your own data type (with an appropriately-defined accessor like the one provided), you can do something similar:
_time :: Lens' CheckersState Int
_time f state = (\newTime -> state { time = newTime }) <$> f (time state)
onemove = over _time (+1)
So there’s plenty of fancy ways to do it. But the most general way is to use pattern-matching.

As icktoofay is saying, using tuples is a code smell, and records with named components is way better.
Also, using Char (and String) is a code smell. To repair it, define a data type that precisely describes what you expect in a cell of the board, like data Colour = None | Red | Black, but see next item.
And, using Lists is also a code smell. You actually want something like type Board = Data.Map.Map Pos Colour or Data.Map.Map Pos (Maybe Colour') with data Colour' = Red | Black.
Oh, and Int is also a code smell. You could define newtype Row = Row Int ; newtype Col = Col Int ; type Pos = (Row,Col). Possibly deriving Num for the newtypes, but it's not clear, e.g., you don't want to multiply row numbers. Perhaps deriving (Eq,Ord,Enum) is enough, with Enum you get pred and succ.
(Ah - this Pos is using a tuple, thus it`s smelly? Well, no, 2-tuples is allowed, sometimes.)

You use pattern matching to decompose the tuple into variables.
onemove (i, c, board, (x, y)) = <do something> (i, c, board)
However, you should define a separate data structure for the board to make your intention clear. I don't know what the meaning of the first two values. See: http://learnyouahaskell.com/making-our-own-types-and-typeclasses

Related

Haskell: Assigning unique char to matrix values if x > 0

So my goal for the program is for it to receive an Int matrix for input, and program converts all numbers > 0 to a unique sequential char, while 0's convert into a '_' (doesn't matter, just any character not in the sequence).
eg.
main> matrixGroupings [[0,2,1],[2,2,0],[[0,0,2]]
[["_ab"],["cd_"],["__e"]]
The best I've been able to achieve is
[["_aa"],["aa_"],["__a"]]
using:
matrixGroupings xss = map (map (\x -> if x > 0 then 'a' else '_')) xss
As far as I can tell, the issue I'm having is getting the program to remember what its last value was, so that when the value check is > 0, it picks the next char in line. I can't for the life of me figure out how to do this though.
Any help would be appreciated.
Your problem is an instance of an ancient art: labelling of various structures with a stream of
labels. It dates back at least to Chris Okasaki, and my favourite treatment is by Jeremy
Gibbons.
As you can see from these two examples, there is some variety to the way a structure may be
labelled. But in this present case, I suppose the most straightforward way will do. And in Haskell
it would be really short. Let us dive in.
The recipe is this:
Define a polymorphic type for your matrices. It must be such that a matrix of numbers and a
matrix of characters are both rightful members.
Provide an instance of Traversable class. It may in many cases be derived automagically.
Pick a monad to your liking. One simple choice is State. (Actually, that is the only choice I
can think of.)
Create an action in this monad that takes a number to a character.
Traverse a matrix with this action.
Let's cook!
A type may be as simple as this:
newtype Matrix a = Matrix [[a]] deriving Show
It is entirely possible that the inner lists will be of unequal length — this type does not
protect us from making a "ragged" matrix. This is poor design. But I am going to skim over
it for now. Haskell provides an endless depth for perfection. This type is good enough for
our needs here.
We can immediately define an example of a matrix:
example :: Matrix Int
example = Matrix [[0,2,1],[2,2,0],[0,0,2]]
How hard is it to define a Traversable? 0 hard.
{-# language DeriveTraversable #-}
...
newtype Matrix a = Matrix [[a]] deriving (Show, Functor, Foldable, Traversable)
Presto.
Where do we get labels from? It is a side effect. The function reaches somewhere, takes a
stream of labels, takes the head, and puts the tail back in the extra-dimensional pocket. A
monad that can do this is State.
It works like this:
label :: Int -> State String Char
label 0 = return '_'
label x = do
ls <- get
case ls of
[ ] -> error "No more labels!"
(l: ls') -> do
put ls'
return l
I hope the code explains itself. When a function "creates" a monadic value, we call it
"effectful", or an "action" in a given monad. For instance, print is an action that,
well, prints stuff. Which is an effect. label is also an action, though in a different
monad. Compare and see for youself.
Now we are ready to cook a solution:
matrixGroupings m = evalState (traverse label m) ['a'..'z']
This is it.
λ matrixGroupings example
Matrix ["_ab","cd_","__e"]
Bon appetit!
P.S. I took all glory from you, it is unfair. To make things fun again, I challenge you for an exercise: can you define a Traversable instance that labels a matrix in another order — by columns first, then rows?

Creating list of values of the same typeclass but different types

I'm new to Haskell and trying to do something which I'm sure is easy but I'm not seeing the right way to do it.
What I want is a list of values of a particular typeclass, but different types of that typeclass. Eg:
class Shape a where
area :: a -> Double
numVertices :: a -> Integer
data Triangle = Triangle {...}
data Square = Square {...}
instance Shape Triangle where ...
instance Shape Square where ...
x = [Triangle (...), Square (...)]
I'm getting a compiler error because the list has different types. What's the right way to do what I'm trying to do here? The only thing I've been able to come up with is doing something like this:
data WrappedShape = WrappedShape {
getArea :: () -> Double
, getNumVertices :: () -> Integer
}
wrap s = WrappedShape {
getArea = \ () -> area s
, getNumVertices = \ () -> vertices s
}
x = [wrap (Triangle (...)), wrap (Square (...))]
This works, but it's heavy on boilerplate, since I have to effectively define Shape twice and with differently-named members. What's the standard way to do this sort of thing?
If you just need a few different shapes, you can enumerate each shape as a constructor, here is a example:
data SomeShapes = Triangle {...}
| Square {...}
instance Shape SomeShapes where
area (Triangle x) = ...
area (Square x) = ....
now you can put them in a list, because they are same type of SomeShapes
[Triangle {...}, Square {...}]
Your wrapped type is probably the best idea.
It can be improved by noting that, in a lazy language like Haskell, the type () -> T essentially works like the plain T. You probably want to delay computation and write stuff like let f = \ () -> 1+2 which does not perform addition until the function f is called with argument (). However, let f = 1+2 already does not perform addition until f is really needed by some other expression -- this is laziness.
So, we can simply use
data WrappedShape = WrappedShape {
getArea :: Double
, getNumVertices :: Integer
}
wrap s = WrappedShape {
getArea = area s
, getNumVertices = vertices s
}
x = [wrap (Triangle (...)), wrap (Square (...))]
and forget about passing () later on: when we will access a list element, the area/vertices will be computed (whatever we need). That is print (getArea (head x)) will compute the area of the triangle.
The \ () -> ... trick is indeed needed in eager languages, but in Haskell it is an anti-pattern. Roughly, in Haskell everything has a \ () -> ... on top, roughly speaking, s o there's no need to add another one.
These is another solution to your problem, which is called an "existential type". However, this sometimes turns into an anti-pattern as well, so I do not recommend to use it lightly.
It would work as follows
data WrappedShape = forall a. Shape a => WrappedShape a
x = [WrappedShape (Triangle ...), WrappedShape (Square ...)]
exampleUsage = case head x of WrappedShape s -> area s
This is more convenient when the type class has a lots of methods, since we do not have to write a lot of fields in the wrapped type.
The main downside of this technique is that it involves more complex type machinery, for no real gain. I mean a basic list [(Double, Integer)] has the same functionality of [WrappedShape] (list of existentials), so why bother with the latter?
Luke Palmer wrote about this anti-pattern. I do not agree with that post completely, but I think he does have some good points.
I do not have a clear-cut line where I would start using existentials over the basic approach, but these factors are what I would consider:
How many methods does the type class have?
Are there any methods of the type class where the type a (the one related to the class) appears not only as an argument? E.g. a method foo :: a -> (String, a)?

Outputting the contents of a list of a custom data type

I have a custom data type Movie = String Int [(String,Int)] (Movie Name Year [(Fan,Rating)] and want to do a couple of things:
First I want to make a function that averages the Ints from the list of tuples and just outputs that number. So far I have this incomplete function:
avgRating :: [DataType] -> Int
avgRating [(Movie a b [(fan,rating)])] = sumRatings / (length [<mylist>])
Here I need a function sumRatings to recurse through the list and sum all the ratings, but i'm not sure where to start.
The other issue I have here is that i'm not sure what to put where <mylist> is as I would normally give the list a variable name and then use it there, but since I have split the list up to define other variables I can't name it.
I hope that makes sense, thanks.
I'm guessing you have a data structure defined as
data Movie = Movie String Int [(String, Int)]
While this works, it can be a bit cumbersome to work with when you have that many fields. Instead, you can leverage type aliases and record syntax as
type Name = String
type Year = Int
type Rating = Int
data Movie = Movie
{ mName :: Name
, mYear :: Year
, mRatings :: [(Name, Rating)]
} deriving (Eq, Show)
Now things are a bit more explicit and easier to work with. The mName, mYear, and mRatings functions will take a Movie and return the corresponding field from it. Your Movie constructor still works in the same way too, so it won't break existing code.
To calculate the average of the ratings, you really want a function that extracts all the ratings for a movie and aggregates them into a list:
ratings :: Movie -> [Rating]
ratings mov = map snd $ mRatings mov
Then you just need an average function. This will be a bit different because you can't calculate the average of Ints directly, you'll have to convert to a floating point type:
average :: [Rating] -> Float -- Double precision isn't really needed here
average rs = fromIntegral (sum rs) / fromIntegral (length rs)
The fromIntegral function converts an Int to a Float (the actual type signature is a bit more general). Since both the sum of Ints is an Int and the length of a list is always an Int, you need to convert both.
Now you can just compose these into a single function:
movieAvgRating :: Movie -> Float
movieAvgRating = average . ratings
Now, if you need to calculate the average ratings for several movies, you can apply ratings to each of them, aggregate them into a single list of ratings, then call average on that. I would suggest looking at the concatMap function. You'll be wanting to make a function like
moviesAvgRating :: [Movie] -> Float
moviesAvgRating movs = average $ ???
To answer your second question first, you can bind to a variable and unpack it simultaneously using #:
avgRating [(Movie a b mylist#[(fan, rating)])] = …
Note also that if you’re not going to be using variables that you unpack, it’s Haskell convention to bind them to _:
avgRating [(Movie _ _ mylist#[(fan, rating)])] = …
This helps readers focus on what’s actually important.
I don’t want to just give you the solution to your recursion problem, because learning to write recursive functions is an important and rewarding part of Haskell programming. (If you really want me to spoil it for you, let me know in a comment.) The basic idea, however, is that you need to think about two different cases: a base case (where the recursion stops) and a recursive case. As an example, consider the built-in sum function:
sum :: Num a => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
Here, the base case is when sum gets an empty list – it simply evaluates to 0. In the recursive case, we assume that sum can already produce the sum of a smaller list, and we extend it to cover a larger list.
If you’re having trouble with recursion in general, Harold Abelson and Gerald Jay Sussman present a detailed discussion on the topic in Structure and Interpretation of Computer Programs, 2nd ed., The MIT Press (Cambridge), 1996, starting on p. 21 (§§1.1.7–1.2). It’s in Scheme, not Haskell, but the languages are sufficiently similar – at least at this conceptual level – that each can serve as a decent model for the other.

What are lenses used/useful for?

I can't seem to find any explanation of what lenses are used for in practical examples. This short paragraph from the Hackage page is the closest I've found:
This modules provides a convienient way to access and update the elements of a structure. It is very similar to Data.Accessors, but a bit more generic and has fewer dependencies. I particularly like how cleanly it handles nested structures in state monads.
So, what are they used for? What benefits and disadvantages do they have over other methods? Why are they needed?
They offer a clean abstraction over data updates, and are never really "needed." They just let you reason about a problem in a different way.
In some imperative/"object-oriented" programming languages like C, you have the familiar concept of some collection of values (let's call them "structs") and ways to label each value in the collection (the labels are typically called "fields"). This leads to a definition like this:
typedef struct { /* defining a new struct type */
float x; /* field */
float y; /* field */
} Vec2;
typedef struct {
Vec2 col1; /* nested structs */
Vec2 col2;
} Mat2;
You can then create values of this newly defined type like so:
Vec2 vec = { 2.0f, 3.0f };
/* Reading the components of vec */
float foo = vec.x;
/* Writing to the components of vec */
vec.y = foo;
Mat2 mat = { vec, vec };
/* Changing a nested field in the matrix */
mat.col2.x = 4.0f;
Similarly in Haskell, we have data types:
data Vec2 =
Vec2
{ vecX :: Float
, vecY :: Float
}
data Mat2 =
Mat2
{ matCol1 :: Vec2
, matCol2 :: Vec2
}
This data type is then used like this:
let vec = Vec2 2 3
-- Reading the components of vec
foo = vecX vec
-- Creating a new vector with some component changed.
vec2 = vec { vecY = foo }
mat = Mat2 vec2 vec2
However, in Haskell, there's no easy way of changing nested fields in a data structure. This is because you need to re-create all of the wrapping objects around the value that you are changing, because Haskell values are immutable. If you have a matrix like the above in Haskell, and want to change the upper right cell in the matrix, you have to write this:
mat2 = mat { matCol2 = (matCol2 mat) { vecX = 4 } }
It works, but it looks clumsy. So, what someone came up with, is basically this: If you group two things together: the "getter" of a value (like vecX and matCol2 above) with a corresponding function that, given the data structure that the getter belongs to, can create a new data structure with that value changed, you are able to do a lot of neat stuff. For example:
data Data = Data { member :: Int }
-- The "getter" of the member variable
getMember :: Data -> Int
getMember d = member d
-- The "setter" or more accurately "updater" of the member variable
setMember :: Data -> Int -> Data
setMember d m = d { member = m }
memberLens :: (Data -> Int, Data -> Int -> Data)
memberLens = (getMember, setMember)
There are many ways of implementing lenses; for this text, let's say that a lens is like the above:
type Lens a b = (a -> b, a -> b -> a)
I.e. it is the combination of a getter and a setter for some type a which has a field of type b, so memberLens above would be a Lens Data Int. What does this let us do?
Well, let's first make two simple functions that extract the getters and setters from a lens:
getL :: Lens a b -> a -> b
getL (getter, setter) = getter
setL :: Lens a b -> a -> b -> a
setL (getter, setter) = setter
Now, we can start abstracting over stuff. Let's take the situation above again, that we want to modify a value "two stories deep." We add a data structure with another lens:
data Foo = Foo { subData :: Data }
subDataLens :: Lens Foo Data
subDataLens = (subData, \ f s -> f { subData = s }) -- short lens definition
Now, let's add a function that composes two lenses:
(#) :: Lens a b -> Lens b c -> Lens a c
(#) (getter1, setter1) (getter2, setter2) =
(getter2 . getter1, combinedSetter)
where
combinedSetter a x =
let oldInner = getter1 a
newInner = setter2 oldInner x
in setter1 a newInner
The code is kind of quickly written, but I think it's clear what it does: the getters are simply composed; you get the inner data value, and then you read its field. The setter, when it is supposed to alter some value a with the new inner field value of x, first retrieves the old inner data structure, sets its inner field, and then updates the outer data structure with the new inner data structure.
Now, let's make a function that simply increments the value of a lens:
increment :: Lens a Int -> a -> a
increment l a = setL l a (getL l a + 1)
If we have this code, it becomes clear what it does:
d = Data 3
print $ increment memberLens d -- Prints "Data 4", the inner field is updated.
Now, because we can compose lenses, we can also do this:
f = Foo (Data 5)
print $ increment (subDataLens#memberLens) f
-- Prints "Foo (Data 6)", the innermost field is updated.
What all of the lens packages do is essentially to wrap this concept of lenses - the grouping of a "setter" and a "getter," into a neat package that makes them easy to use. In a particular lens implementation, one would be able to write:
with (Foo (Data 5)) $ do
subDataLens . memberLens $= 7
So, you get very close to the C version of the code; it becomes very easy to modify nested values in a tree of data structures.
Lenses are nothing more than this: an easy way of modifying parts of some data. Because it becomes so much easier to reason about certain concepts because of them, they see a wide use in situations where you have huge sets of data structures that have to interact with one another in various ways.
For the pros and cons of lenses, see a recent question here on SO.
Lenses provide convenient ways to edit data structures, in a uniform, compositional way.
Many programs are built around the following operations:
viewing a component of a (possibly nested) data structure
updating fields of (possibly nested) data structures
Lenses provide language support for viewing and editing structures in a way that ensures your edits are consistent; that edits can be composed easily; and that the same code can be used for viewing parts of a structure, as for updating the parts of the structure.
Lenses thus make it easy to write programs from views onto structures; and from structures back on to views (and editors) for those structures. They clean up a lot of the mess of record accessors and setters.
Pierce et al. popularized lenses, e.g. in their Quotient Lenses paper, and implementations for Haskell are now widely used (e.g. fclabels and data-accessors).
For concrete use cases, consider:
graphical user interfaces, where a user is editing information in a structured way
parsers and pretty printers
compilers
synchronizing updating data structures
databases and schemas
and many other situations where you have a data structure model of the world, and a editable view onto that data.
As an additional note it is often overlooked that lenses implement a very generic notion of "field access and update". Lenses can be written for all kinds of things, including function-like objects. It requires a bit of abstract thinking to appreciate this, so let me show you an example of the power of lenses:
at :: (Eq a) => a -> Lens (a -> b) b
Using at you can actually access and manipulate functions with multiple arguments depending on earlier arguments. Just keep in mind that Lens is a category. This is a very useful idiom for locally adjusting functions or other things.
You can also access data by properties or alternate representations:
polar :: (Floating a, RealFloat a) => Lens (Complex a) (a, a)
mag :: (RealFloat a) => Lens (Complex a) a
You can go further writing lenses to access individual bands of a Fourier-transformed signal and a lot more.

Haskell Access Tuple Data Inside List Comprehension

I have defined a custom type as follows:
-- Atom reference number, x coordinate, y coordinate, z coordinate, element symbol,
-- atom name, residue sequence number, amino acid abbreviation
type Atom = (Int, Double, Double, Double, Word8, ByteString, Int, ByteString)
I would like to gather all of the atoms with a certain residue sequence number nm.
This would be nice:
[x | x <- p, d == nm]
where
(_, _, _, _, _, _, d, _) = x
where p is a list of atoms.
However, this does not work because I can not access the variable x outside of the list comprehension, nor can I think of a way to access a specific tuple value from inside the list comprehension.
Is there a tuple method I am missing, or should I be using a different data structure?
I know I could write a recursive function that unpacks and checks every tuple in the list p, but I am actually trying to use this nested inside an already recursive function, so I would rather not need to introduce that complexity.
This works:
[x | (_, _, _, _, _, _, d, _) <- p, d == nm]
However, you should really define your own data type here. A three-element tuple is suspicious; an eight-element tuple is very bad news indeed. Tuples are difficult to work with and less type-safe than data types (if you represent two different kinds of data with two tuples with the same element types, they can be used interchangeably). Here's how I'd write Atom as a record:
data Point3D = Point3D Double Double Double
data Atom = Atom
{ atomRef :: Int
, atomPos :: Point3D
, atomSymbol :: Word8
, atomName :: ByteString
, atomSeqNum :: Int
, atomAcidAbbrev :: ByteString
} deriving (Eq, Show)
(The "atom" prefix is to avoid clashing with the names of fields in other records.)
You can then write the list comprehension as follows:
[x | x <- p, atomSeqNum x == nm]
As a bonus, your definition of Atom becomes self-documenting, and you reap the benefits of increased type safety. Here's how you'd create an Atom using this definition:
myAtom = Atom
{ atomRef = ...
, atomPos = ...
, ... etc. ...
}
By the way, it's probably a good idea to make some of the fields of these types strict, which can be done by putting an exclamation mark before the type of the field; this helps avoid space leaks from unevaluated thunks building up. For instance, since it doesn't make much sense to evaluate a Point3D without also evaluating all its components, I would instead define Point3D as:
data Point3D = Point3D !Double !Double !Double
It would probably be a good idea to make all the fields of Atom strict too, although perhaps not all of them; for example, the ByteString fields should be left non-strict if they're generated by the program, not always accessed and possibly large. On the other hand, if their values are read from a file, then they should probably be made strict.
You should definitely use a different structure. Instead of using a tuple, take a look at records.
data Atom = Atom { reference :: Int
, position :: (Double, Double, Double)
, symbol :: Word8
, name :: ByteString
, residue :: Int
, abbreviation :: ByteString
}
You can then do something like this:
a = Atom ...
a {residue=10} -- this is now a with a residue of 10

Resources