Representing a chessboard in Haskell - haskell

I'm trying to implement a function in Haskell that returns a list containing all possible moves for the player who's up. The function's only argument is a String composed of an actual state of the board (in Forsyth-Edwards Notation ) followed by the moving player(b/w).
Notation example : rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w (starting board state)
A move is transmitted as a string of the form [origin]-[destination]. The destination is always a position of the form [column][row], where the lower left square is called a1 and the upper right square is called h8. A move would be for example the move "b3-c4". (no castling/En-passant).
In Java I would use a 2d Array for the Board, but in Haskell I can't find a similar solution (I'm new to functional programming).
What would be a good way/data structure to represent the chess board in?

There are two primary options for storing a board state. The first is a 2D list of Maybe, where a piece would be represented as, e.g. Just $ Piece Black King and a blank square would be represented as Nothing. This optimizes determining if a square is occupied over listing where pieces are (which might be important if you plan to add rendering later):
type Board = Vector (Vector (Maybe Piece))
data Piece = Piece { color :: Color
, type :: PieceType }
The second option is to store a list of pieces and their locations. This implementation is faster to enumerate the locations of all pieces, but slower to check if there is a piece on a particular square:
type Pieces = [Placement]
type Placement = { position :: Position
, piece :: Piece }
data Position =
Pos { rank :: Int
, file :: Int }
deriving (Show, Eq)
data Piece =
Piece { color :: Color
, ptype :: PieceType }
deriving Show
EDIT: It's worth noting that with an 8x8 grid and a maximum of 32 pieces on the board, the performance hit either way is going to be minimal unless you're doing a lot of calculations.

Data.Vector, has constant time lookup by index.
A chessboard can be represented as a Vector (Vector (Maybe Piece)). To define Piece, see ADTs

Related

Haskell evaluating properties of a data type only once when first accessed?

In imperative/object oriented programming with mutable state, it would be very common and useful to declare a structure such as the following:
struct RigidBody {
float m_mass;
float m_inverseMass;
Mat3 m_localInverseInertiaTensor;
Mat3 m_globalInverseInertiaTensor;
Vec3 m_globalCentroid;
Vec3 m_localCentroid;
Vec3 m_position;
Mat3 m_orientation;
Vec3 m_linearVelocity;
Vec3 m_angularVelocity;
};
Source: http://allenchou.net/2013/12/game-physics-motion-dynamics-implementations/
There are many properties here that are able to be computed directly from others, such as m_inverseMass from m_mass. In a stateless programming language like Haskell, getting derived values is easy enough:
data RigidBody = RigidBody {mass :: Float}
inverseMass :: RigidBody -> Float
inverseMass body = 1 / mass body
But this computes the inverseMass every time we need it, which can get expensive especially in domains where performance is critical, like physics simulation. I've considered memoization, but I wasn't sure if this is a good way of expressing this lazy evaluation of dependent properties, as it seemed to be a complicated solution. How would I store derivative values without having to recompute them?
As #4castle and #Shersh note, a simple approach would be to include the derived value in the data type:
data RigidBody = RigidBody
{ m_mass :: Float
, m_inverseMass :: Float }
and then use a smart constructor to make new RigidBodys:
rigidBody mass = RigidBody mass (1/mass)
The expression 1/mass will create a thunk for m_inverseMass which, after it is first evaluated, will be available without recalculation, so it provides a sort of auto memoization.
More general transformations, like changing the position and properly updating all the global* fields based on the local* values would be handled in a similar manner. As a simplified example:
module Rigid where
type Vec3 = Double -- just to type check
data RigidBody = RigidBody
{ m_mass :: Float
, m_inverseMass :: Float
, m_pos :: Vec3
, m_localCentroid :: Vec3
, m_globalCentroid :: Vec3
}
rigidBody mass pos centroid =
RigidBody mass (1/mass) pos centroid (centroid + pos)
move body delta =
rigidBody (m_mass body)
(m_pos body + delta)
(m_localCentroid body)
In an application that's performance critical, you would want to take steps to introduce strictness in appropriate places so you don't build up huge piles of unevaluated thunks.
You can store inverseMass as Maybe Float inside RigidBody. When inverseMass is Just someMass you just extract this value. If it's Nothing you compute it and store inside RigidBody. The problem is with this store part. Because as you may know objects are immutable in Haskell.
Naive but simple solution would be to return RigidBody after every computation like this:
data RigidBody = RigidBody
{ rigidBodyMass :: Float
, rigidBodyInverseMass :: Maybe Float }
inverseMass :: RigidBody -> (Float, RigidBody)
inverseMass b#(RigidBody _ (Just inv)) = (inv, b)
inverseMass (RigidBody mass Nothing) = let inv = 1 / mass
in (inv, RigidBody mass (Just inv))
If you have a lot of such fields you may find such approach extremely tedious. And it's not very convenient to write code using such functions. So here is the place where State monad becomes handy. State monad can just keep current RigidBody inside explicit state and update it accordingly through all you stateful computation. Like this:
inverseMass :: State RigidBody Float
inverseMass = do
RigitBody inv maybeInverse <- get
case maybeInverse of
Just inv -> pure inv
Nothing -> do
let inv = 1 / mass
put $ RigidBody mass (Just inv)
pure inv
Later you can just use inverseMass multiple times and only during your first call inverse of mass will be calculated.
You see, in imperative programming languages like C++ state is explicit. You want to update fields of RigidBody. So basically you have some object of type RigidBody which stores some states. Because state is implicit you don't need to specify in your functions that they change fields of RigidBody. In Haskell (and every good programming language) you specify explicitly what is your state and how you will change it. You specify explicitly what objects you want to work with. inverseMass monadic action (or just function if you want) will update your explicit state depending on the current state at the moment of calling this function. This is more or less idiomatic approach in Haskell for such sort of tasks.
Well, another idiomatic solution: just create values of your data type with all fields set to some function calls. Because Haskell is lazy such fields are calculated first time only when they are needed.

type parameters in Haskell

I want to create a type Pixel, and make it an instance of the Eq and Show class. However, i've been reading information from a lot of places, and got really confused with this.
Here's some info on the type i need to create:
I have to store two numbers (the position of the pixel and a value from 0 to 255).
Two pixels are equal if they have the same value, whatever their position is.
For the Show instance, i need to print the position and the value.
Here's my attempt at this:
type position = Float
type greyScale = Int
type Pixel = (position, greyScale)
instance Eq Pixel where
greyScale == greyScale = True
instance Show Pixel where
show position = position
show greyScale = greyScale
is this a correct way to do it ?
Type names have to start with a capital letter. So, your definitions actually should look like this, since you are only defining type synonyms:
type Position = Float
type GreyScale = Int
For Pixel: It looks like you wanted to define a data type, not just a synonym, so you should do something like this:
data Pixel = Pixel Position GreyScale
Next: The Eq instance compares two Pixels, so you have to represent them as such:
instance Eq Pixel where
Pixel pos1 greyScale1 == Pixel pos2 greyScale2 = greyScale1 == greyScale2
greyScale1 == greyScale2 just compares the two greyScales, which is what you want.
Also, I would not recommend overwriting Show instances to assure that read . show == id holds. (You can automatically derive specific instances by adding deriving (Instance1, Instance2, ..) after the datatype declaration). Rather than meddling with it I would define separate functions:
showPosition :: Pixel -> String
showPosition (Pixel position greyScale) = show position
and
showGreyscale :: Pixel -> String
showGreyscale (Pixel position greyScale) = show greyScale

Design for typeclass representing "species" in Haskell

The following simplified datatype is the base of all the objects of a game:
data Object = Object { logic :: Logic, picture :: Picture }
data Logic = Logic { geometry :: Geometry, someAttributes :: SomeAttributes }
data Geometry = Geometry { coords :: Point, size :: Point }
data SomeAttributes = SomeAttributes { life :: Int, hasGravity :: Bool }
The objects are created by functions:
hero position = Object
(Logic
(Geometry position (Point 25 55))
(SomeAttributes 100 True))
PictureConstructor1
enemy position = Object
(Logic
(Geometry position (Point 25 25))
(SomeAttributes 3 True))
PictureConstructor2
bullet position = Object
(Logic
(Geometry position (Point 5 5))
(SomeAttributes 0 False))
PictureConstructor3
--etc. for blocks and everything else
Example of game structure:
[hero (Point 0 0), enemy (Point 50 0), enemy (Point 100 0), block (Point 0 (negate 30)), block (Point 50 (negate 30)), block (Point 100 (negate 30))]
Then, an advance function takes this list and apply gravity, collisions, ..., thus making the objets move, die, ...
This function is of type [Object] -> [Object], but it doesn't change all the fields of Object: only coords and life are changed, while size and hasGravity, for example, always remain constant, untouched.
This constant data represents some kind of "specy attributes", or class attributes, but the "instances" carry them around, which is not safe, heavy for memory and unpractical for serialization.
I thought of making a typeclass and every instance would provide their "constants" and a constructor for fields that can change. I can't think of something better than:
class Object a where
size :: Point
baseLife :: Point
hasGravity :: Bool
picture :: Picture
data Hero = Hero { coords :: Point, currentLife :: Int }
instance Object Hero where
size = Point 25 55
baseLife = 100
hasGravity = True
picture = PictureConstructor1
setHero a#(Hero xy _) = Hero xy (baseLife a)
It's lighter and safer, but it's rather ugly because it has lost its structure (no more Logic, Geometry, ...). I think I would use lambda types if they existed :p.
Please share your ideas on how to fix these issues or alternative models you can think about.
The problem is that all these species-specific fields can be modified by other functions, but the only thing that can change during the game is, let's say, the position and the life points.
Since all data structures in haskell are immutable, I assume that when you say modify, you mean that other functions can construct new (possibly different) objects using the data constructors.
If you want to prevent that from happening, you could put the datatypes together with the functions that construct them (hero, enemy and bullet) into an extra module which only exports the type constructors of your datatypes together with the functions for accessing fields and the construction functions, but not the data constructors.
module GameData (Object, Logic, Geometry, SomeAttributes, logic, picture, geometry, someAttributes, coords, size, life, hasGravity, hero, enemy, bullet)
data Object = CreateObject { logic :: Logic, picture :: Picture }
data Logic = CreateLogic { geometry :: Geometry, someAttributes :: SomeAttributes }
data Geometry = CreateGeometry { coords :: Point, size :: Point }
data SomeAttributes = CreateSomeAttributes { life :: Int, hasGravity :: Bool }
hero position = ...
enemy position = ...
bullet position = ...
Then you could choose which data constructors you want to expose. Maybe it makes sense to put all the 'mutable' data into its own datatype, so you can export the data constructor of that datatype but not the data constructors of the other datatypes.
Once you have everything organized like that, you have very tight control over how your objects can be constructed, since that modules is the only thing that can do this construction, the other modules only have access to the hero enemy and bullet functions.

How to model a 2D world in Haskell

I'm making a game. The game consists of an infinite plane. Units must be on a discrete square, so they can be located with a simple Location { x :: Int, y :: Int }
There might be many kinds of Units. Some might be creatures, and some are just objects, like a block of stone, or wood (think 2d minecraft there). Many will be empty (just grass or whatever).
How would you model this in Haskell? I've considered doing the below, but what about Object vs Creature? they might have different fields? Normalize them all on Unit?
data Unit = Unit { x :: Int, y :: Int, type :: String, ... many shared properties... }
I've also considered having a location type
data Location = Location { x :: Int, y :: Int, unit :: Unit }
-- or this
data Location = Location { x :: Int, y :: Int }
data Unit = Unit { unitFields... , location :: Location }
Do you have any ideas? In an OO language, I probably would have had Location or Unit inherit from the other, and made the specific types of Unit inherit from each other.
Another consideration is this will be sending lots of these objects over the wire, so I'll need to serialize them to JSON for use on the client, and don't want to write tons of parsing boilerplate.
Location is just a simple two-dimensional Point type.
I would advise against tying Units to the location they're in; just use a Map Location Unit to handle the map between positions on the grid and what (if anything) is present there.
As far as the specific types of Unit go, I would, at the very least, recommend factoring common fields out into a data type:
data UnitInfo = UnitInfo { ... }
data BlockType = Grass | Wood | ...
data Unit
= NPC UnitInfo AgentID
| Player UnitInfo PlayerID
| Block UnitInfo BlockType
or similar.
Generally, factor common things out into their own data-type, and keep data as simple and "isolated" as possible (i.e. move things like "what location is this unit at?" into separate structures associating the two, so that individual data-types are as "timeless", reusable and abstract as possible).
Having a String for the "type" of a Unit is a strong antipattern in Haskell; it generally indicates you're trying to implement dynamic typing or OOP structures with data types, which is a bad fit.
Your JSON requirement complicates things, but this FAQ entry shows a good example of how to idiomatically achieve this kind of genericity in Haskell with no String typing or fancy type-class hacks, using functions and data-types as the primary units of abstraction. Of course, the former causes you problems here; it's hard to serialise functions as JSON. However, you could maintain a map from an ADT representing a "type" of creature or block, etc., and its actual implementation:
-- records containing functions to describe arbitrary behaviour; see FAQ entry
data BlockOps = BlockOps { ... }
data CreatureOps = CreatureOps { ... }
data Block = Block { ... }
data Creature = Creature { ... }
data Unit = BlockUnit Block | CreatureUnit Creature
newtype GameField = GameField (Map Point Unit)
-- these types are sent over the network, and mapped *back* to the "rich" but
-- non-transferable structures describing their behaviour; of course, this means
-- that BlockOps and CreatureOps must contain a BlockType/CreatureType to map
-- them back to this representation
data BlockType = Grass | Wood | ...
data CreatureType = ...
blockTypes :: Map BlockType BlockOps
creatureTypes :: Map CreatureType CreatureOps
This lets you have all the extensibility and don't-repeat-yourself nature of typical OOP structures, while keeping the functional simplicity and allowing simple network transfer of game states.
Generally, you should avoid thinking in terms of inheritance and other OOP concepts; instead, try to think of dynamic behaviour in terms of functions and composition of simpler structures. A function is the most powerful tool in functional programming, hence the name, and can represent any complex pattern of behaviour. It's also best not to let requirements like network play influence your basic design; like the example above, it's almost always possible to layer these things on top of a design built for expressiveness and simplicity, rather than constraints like communication format.

Can good type systems distinguish between matrices in different bases?

My program (Hartree-Fock/iterative SCF) has two matrices F and F' which are really the same matrix expressed in two different bases. I just lost three hours of debugging time because I accidentally used F' instead of F. In C++, the type-checker doesn't catch this kind of error because both variables are Eigen::Matrix<double, 2, 2> objects.
I was wondering, for the Haskell/ML/etc. people, whether if you were writing this program you would have constructed a type system where F and F' had different types? What would that look like? I'm basically trying to get an idea how I can outsource some logic errors onto the type checker.
Edit: The basis of a matrix is like the unit. You can say 1L or however many gallons, they both mean the same thing. Or, to give a vector example, you can say (0,1) in Cartesian coordinates or (1,pi/2) in polar. But even though the meaning is the same, the numerical values are different.
Edit: Maybe units was the wrong analogy. I'm not looking for some kind of record type where I can specify that the first field will be litres and the second gallons, but rather a way to say that this matrix as a whole, is defined in terms of some other matrix (the basis), where the basis could be any matrix of the same dimensions. E.g., the constructor would look something like mkMatrix [[1, 2], [3, 4]] [[5, 6], [7, 8]] and then adding that object to another matrix would type-check only if both objects had the same matrix as their second parameters. Does that make sense?
Edit: definition on Wikipedia, worked examples
This is entirely possible in Haskell.
Statically checked dimensions
Haskell has arrays with statically checked dimensions, where the dimensions can be manipulated and checked statically, preventing indexing into the wrong dimension. Some examples:
This will only work on 2-D arrays:
multiplyMM :: Array DIM2 Double -> Array DIM2 Double -> Array DIM2 Double
An example from repa should give you a sense. Here, taking a diagonal requires a 2D array, returns a 1D array of the same type.
diagonal :: Array DIM2 e -> Array DIM1 e
or, from Matt sottile's repa tutorial, statically checked dimensions on a 3D matrix transform:
f :: Array DIM3 Double -> Array DIM2 Double
f u =
let slabX = (Z:.All:.All:.(0::Int))
slabY = (Z:.All:.All:.(1::Int))
u' = (slice u slabX) * (slice u slabX) +
(slice u slabY) * (slice u slabY)
in
R.map sqrt u'
Statically checked units
Another example from outside of matrix programming: statically checked units of dimension, making it a type error to confuse e.g. feet and meters, without doing the conversion.
Prelude> 3 *~ foot + 1 *~ metre
1.9144 m
or for a whole suite of SI units and quanities.
E.g. can't add things of different dimension, such as volumes and lengths:
> 1 *~ centi litre + 2 *~ inch
Error:
Expected type: Unit DVolume a1
Actual type: Unit DLength a0
So, following the repa-style array dimension types, I'd suggest adding a Base phantom type parameter to your array type, and using that to distinguish between bases. In Haskell, the index Dim
type argument gives the rank of the array (i.e. its shape), and you could do similarly.
Or, if by base you mean some dimension on the units, using dimensional types.
So, yep, this is almost a commodity technique in Haskell now, and there's some examples of designing with types like this to help you get started.
This is a very good question. I don't think you can encode the notion of a basis in most type systems, because essentially anything that the type checker does needs to be able to terminate, and making judgments about whether two real-valued vectors are equal is too difficult. You could have (2 v_1) + (2 v_2) or 2 (v_1 + v_2), for example. There are some languages which use dependent types [ wikipedia ], but these are relatively academic.
I think most of your debugging pain would be alleviated if you simply encoded the bases in which you matrix works along with the matrix. For example,
newtype Matrix = Matrix { transform :: [[Double]],
srcbasis :: [Double], dstbasis :: [Double] }
and then, when you M from basis a to b with N, check that N is from b to c, and return a matrix with basis a to c.
NOTE -- it seems most people here have programming instead of math background, so I'll provide short explanation here. Matrices are encodings of linear transformations between vector spaces. For example, if you're encoding a rotation by 45 degrees in R^2 (2-dimensional reals), then the standard way of encoding this in a matrix is saying that the standard basis vector e_1, written "[1, 0]", is sent to a combination of e_1 and e_2, namely [1/sqrt(2), 1/sqrt(2)]. The point is that you can encode the same rotation by saying where different vectors go, for example, you could say where you're sending [1,1] and [1,-1] instead of e_1=[1,0] and e_2=[0,1], and this would have a different matrix representation.
Edit 1
If you have a finite set of bases you are working with, you can do it...
{-# LANGUAGE EmptyDataDecls #-}
data BasisA
data BasisB
data BasisC
newtype Matrix a b = Matrix { coefficients :: [[Double]] }
multiply :: Matrix a b -> Matrix b c -> Matrix a c
multiply (Matrix a_coeff) (Matrix b_coeff) = (Matrix multiplied) :: Matrix a c
where multiplied = undefined -- your algorithm here
Then, in ghci (the interactive Haskell interpreter),
*Matrix> let m = Matrix [[1, 2], [3, 4]] :: Matrix BasisA BasisB
*Matrix> m `multiply` m
<interactive>:1:13:
Couldn't match expected type `BasisB'
against inferred type `BasisA'
*Matrix> let m2 = Matrix [[1, 2], [3, 4]] :: Matrix BasisB BasisC
*Matrix> m `multiply` m2
-- works after you finish defining show and the multiplication algorithm
While I realize this does not strictly address the (clarified) question – my apologies – it seems relevant at least in relation to Don Stewart's popular answer...
I am the author of the Haskell dimensional library that Don referenced and provided examples from. I have also been writing – somewhat under the radar – an experimental rudimentary linear algebra library based on dimensional. This linear algebra library statically tracks the sizes of vectors and matrices as well as the physical dimensions ("units") of their elements on a per element basis.
This last point – tracking physical dimensions on a per element basis – is rather challenging and perhaps overkill for most uses, and one could even argue that it makes little mathematical sense to have quantities of different physical dimensions as elements in any given vector/matrix. However, some linear algebra applications of interest to me such as kalman filtering and weighted least squares estimation typically use heterogeneous state vectors and covariance matrices.
Using a Kalman filter as an example, consider a state vector x = [d, v] which has physical dimensions [L, LT^-1]. The next (future) state vector is predicted by multiplication by the state transition matrix F, i.e.: x' = F x_. Clearly for this equation to make sense F cannot be arbitrary but must have size and physical dimensions [[1, T], [T^-1, 1]]. The predict_x' function below statically ensures that this relationship holds:
predict_x' :: (Num a, MatrixVector f x x) => Mat f a -> Vec x a -> Vec x a
predict_x' f x_ = f |*< x_
(The unsightly operator |*< denotes multiplication of a matrix on the left with a vector on the right.)
More generally, for an a priori state vector x_ of arbitrary size and with elements of arbitrary physical dimensions, passing a state transition matrix f with "incompatible" size and/or physical dimensions to predict_x' will cause a compile time error.
In F# (which originally evolved from OCaml), you can use units of measure. Andrew Kenned, who designed the feature (and also created a very interesting theory behind it) has a great series of articles that demonstrate it.
This can quite likely be used in your scenario - although I don't fully understand the question. For example, you can declare two unit types like this:
[<Measure>] type litre
[<Measure>] type gallon
Adding litres and gallons gives you a compile time error:
1.0<litre> + 1.0<gallon> // Error!
F# doesn't automatically insert conversion between different units, but you can write a conversion function:
let toLitres gal = gal * 3.78541178<litre/gallon>
1.0<litre> + (toLitres 1.0<gallon>)
The beautiful thing about units of measure in F# is that they are automatically inferred and functions are generic. If you multiply 1.0<gallon> * 1.0<gallon>, the result is 1.0<gallon^2>.
People have used this feature for various things - ranging from conversion of virtual meters to screen pixels (in solar system simulations) to converting currencies (dollars in financial systems). Although I'm not expert, it is quite likely that you could use it in some way for your problem domain too.
If it's expressed in a different base, you can just add a template parameter to act as the base. That will differentiate those types. A float is a float is a float- if you don't want two float values to be the same if they actually have the same value, then you need to tell the type system about it.

Resources