haskell state and typeclasses - haskell

how can i group getX and putX in a class instance ?
the code below is an answer for this post Class set method in Haskell using State-Monad
import Control.Monad.State
data Point = Point { x :: Int, y :: Int } deriving Show
getX :: State Point Int
getX = get >>= return . x
putX :: Int -> State Point ()
putX newVal = do
pt - get
put (pt { x = newVal })
increaseX :: State Point ()
increaseX = do
x - getX
putX (x + 1)
Later I hope I will implement setters and getters for a hierarchy of 2 classes, but for now i just wanna do something like this:
class A a where
putX :: Int -> State Point ()
instance A (State Point) where
putX newVal = do
pt - get
put (pt { x = newVal })

You seem to be conflating multiple concepts here, to the point that I'm not sure exactly what you're aiming to accomplish. A few thoughts on what you might be after:
Field access, i.e., a way to inspect or replace a piece of a larger data structure. This doesn't really lend itself to a type class, because for many combinations of "inner field" and "data structure" there will be more than one accessor possible. Abstractions along these lines are often called "lenses".
Stateful references in some generic fashion. For the most part in a State monad this amounts to combining something like the aforementioned lenses with the standard get and put. In this case you could have a type class for the combination of a particular monad and the accessor data type, but it wouldn't really do that much.
Overloading access to a particular field, so that functions can work on any data type that contains an "x" field. In this case I assume you'd also want "y", as some sort of type class for 2D points. This is entirely separate from the above issues, however.
Perhaps you could clarify your goal?

Related

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)?

Does Haskell support anonymous instances of typeclass?

I have the following code in F# (it's from a book)
open System.Collections.Generic
type Table<'T, 'U> =
abstract Item : 'T -> 'U with get
abstract Discard : unit -> unit
let memoizeAndPermitDiscard f =
let lookasideTable = new Dictionary<_, _>(HashIdentity.Structural)
{new Table<'T, 'U> with
member t.Item
with get(n) =
if lookasideTable.ContainsKey(n) then
lookasideTable.[n]
else
let res = f n
lookasideTable.Add(n, res)
res
member t.Discard() =
lookasideTable.Clear()}
let rec fibFast =
memoizeAndPermitDiscard (fun n ->
printfn "computing fibFast %d" n
if n <= 2 then 1 else fibFast.[n - 1] + fibFast.[n - 2])
As we can see the abstract type Table take it's implementation in the function memoizeAndPermitDiscard. Can Haskell do the same?
Apologies in advance: I'm not an F# expert, so I may be misreading the F# code. But if I'm reading it right it's fairly straightforward to translate to Haskell:
data Table t u = Table { get :: t -> IO u, discard :: IO () }
memoize :: Hashable t => (t -> u) -> IO (Table t u)
memoize f = do
tbl <- newHashTable
return Table
{ get = \t -> do
result <- lookupHashTable t tbl
case result of
Nothing -> let u = f t in writeHashTable t u tbl >> return u
Just u -> return u
, discard = clearHashTable tbl
}
I'm assuming some suitable hash table implementation here that offers newHashTable, lookupHashTable, writeHashTable, and clearHashTable. Implementing these (or suggesting a library that offers them) is sort of beside the point of the question, I think.
I'm not an F# expert either, but I believe what you're describing is where you create a anonymous single-use subclass, by declaring in at the point where you create an object how it implements the methods of a superclass or interface? So it's really an anonymous class, not an anonymous instance (or rather, it's no more anonymous than any other object-oriented instance, which typically don't have names inherently, only variable names storing references to them).
It doesn't really make sense to do that with Haskell type classes/instances. The reason is that a Haskell instance represents something very different from an OO instance.
The instances of OO classes are objects (even the instances of interfaces are objects). All of a class' methods will always be invoked on an instance of that class. So it makes sense to create an anonymous subclass of an existing class or interface at the time you create a new object. You basically say how that object implements the required methods, as an alternative to declaring a whole named class of objects that implement the methods the same way, which you could instantiate in multiple places.
The instances of Haskell classes are types (which is why the're called type classes). All of the methods of a class must involve the type somehow, but there is no guarantee that they take an input of the type. For example, consider the class1:
class Monoid' a
where mempty' :: a
mappend' :: a -> a -> a
It doesn't really make sense to say an object is an instance of Monoid'; if I were to create a new object and I wanted to anonymously instantiate Monoid', how would I define mempty'? mempty' isn't an operation I could invoke on my new object, it's an operation that receives no inputs at all (not even an implicit "this") and produces a value2.
And then there's things like:
class Functor' f
where fmap :: (a -> b) -> (f a -> f b)
Nothing ever takes an input of a type f that is an instance of Functor'; it doesn't even make sense to talk about something that might, since the instances of the class Functor' are type constructors that need a type parameter to result in a type, not types that actually contain values. So again, it just makes no sense at the point that I'm creating a new object to say "and here's how this object implements Functor'").
It could potentially make sense to declare a new anonymous type locally, and declare how it implements some type classes at the same time. But Haskell has no syntax for it, no.
Fortunately, you also don't need to create anonymous classes/instances in order to have a one-off collection of functions that conforms to a known interface. Functions are first-class values too, so you can just have type whose fields are functions. Then anywhere you like you can create a new value of that type by providing a definition for all of the function fields. For example:
data MyInterface = MyInterface
{ foo :: Int -> Bool
, bar :: Int -> String
}
example :: MyInterface -> Int -> (Bool, String)
example impl x
= (foo impl x, bar impl x)
main = do
let impl = MyInterface { foo = even, bar = show }
print $ example impl 7
The above program prints (False,"7").
1 I'm using Monoid' rather than Monoid (and similarly Functor') because I'm using simplifications of the real classes. You can see the real definition with :info Monoid in ghci (or look up the documentation) if you're interested.
2 Or alternatively, the class Monoid' mandates that there simply exists a value of each type that instantiates it, and mempty' just is a reference to it.

Abstract records or record interfaces?

I'm using Haskell to make a game, (this is an assignment, so don't judge me) but I'm facing a problem regarding data types.
So what I want is a data type Entity which has a location, velocity, angle and a rotation speed. A record works very well for this idea:
data Entity = Entity {
location :: Vector,
velocity :: Vector,
angle :: Float,
rotation :: Float
}
Now I want instances of Entity, namely Player Rock Pickup and Bullet. But Players Rocks and Bullets must have an extra field, namely health :: Int, and Pickup must have another extra field, namely pickupType :: PickupType.
But I have certain methods which I want to work on any Entity type. For example:
move :: Entity -> Entity
move e#(Entity {location, velocity, angle, rotation}) = e {location = location + velocity, angle = angle + rotation}
I have no idea how to do this or if this is even possible. I wouldn't understand why if it isn't possible, since this is definitely possible in other languages.
Some attempts and why they aren't quite what I desire:
Attempt 1:
type Player = Player {
e :: Entity,
health :: Int
}
This works, but it is really ugly. This, for example, is how you would move a Player:
movePlayer :: Player -> Player
movePlayer p#(e) = p {e = move e}
Which is just really ugly.
Positives:
Easy to create the abstract class.
Easy to create instances.
Easy abstract methods.
Negatives:
Hard to get or set Entity-implemented fields of an instance.
Attempt 2:
class Entity e where
getLocation :: e -> Vector
getVelocity :: e -> Vector
...
setLocation :: Vector -> e -> e
setVelocity :: Vector -> e -> e
...
data Player = Player {
playerLocation :: Vector,
playerVelocity :: Vector,
...
playerHealth :: Int
}
instance Entity Player where
getLocation = location
getVelocity = velocity
...
setLocation l e = e {location = l}
setVelocity v e = e {playerVelocity = v}
...
move :: (Entity e) => e -> e
move e = (setLocation (getLocation e + getVelocity e) . setAngle (getAngle e + getRotation e)) e
Well it works, but I hope we can all agree that their definitions are now really ugly. The abstract methods which work on any Entity also becomes way ugly. The only good thing is that methods like movePlayer become really easy.
movePlayer :: Player -> Player
movePlayer = move
I don't even need to define movePlayer anymore, since I can just use move.
Positives:
Easy to get or set Entity-implemented fields of an instance.
Negatives:
Hard to create the abstract class.
Even harder to create instances.
Hard abstract methods.
Attempt 3:
Give Entity all fields that any instance needs.
data Entity = Entity {
location :: Vector,
velocity :: Vector,
angle :: Float,
rotation :: Float,
health :: Int,
pickupType :: PickupType
}
This way I don't even need to define instances and I can just use Entity. The only problem is that you have a lot of excess data. This is currently what I use and IMO the best solution for my problem, but I still don't like it.
Positives:
Easy to create the abstract class, even though it isn't really abstract anymore.
No need to define instances.
Easy abstract methods.
Easy to get or set Entity-implemented fields of an instance.
Negatives:
A lot of unused data.
You have to define a lot of nonsense fields every time you create an Entity.
So please help me, I can't find any better methods than these three :(
I would go with your first attempt, for a very simple reason:
It accurately captures the intention of a Player - it's an Entity with additional information.
data Player = Player {
e :: Entity
health :: Int
}
While all functions dealing with may be cumbersome to write at first, you will probably never have to see them again, meaning you provided an abstract enough interface in your code not to access the state of a Player directly.
movePlayer :: Player -> Player
movePlayer p#(e) = p {e = move e}
This function is written once and then ideally you never have to deal with internals again.
Additionally, now you can use type classes as they are intended: you can abstract movePlayer in a separate type class such as Movable:
class Movable m where
move :: m -> m
-- Obviously, you can move entities
instance Movable Entity where
move e = -- stuff
But now it's really easy to move Players too:
instance Movable Player where
move (Player entity health) = Player (move entity) health
-- works, since `Entity` is movable
This aside, your type class approach has a major flaw: What about functions a Player has but an Entity doesn't? In this case you would have Player inherit Entity, like this:
class Entity e => Player e where
-- stuff ...
But since Haskell's type classes are open, anything can become a Player, which is not how it's supposed to work (unless, of course, that is your intention).
I would say that your first attempt is the way to go, for the same reasons as given in #ThreeFx's answer. I'm going to suggest a slightly different alternative though.
Given these types:
data Player = Player {
playerEntity :: Entity,
health :: Int
}
data Pickup = Pickup {
pickupEntity :: Entity,
pickupType :: PickupType
}
Instead of having a separate type class for each action that can be done on an Entity, we can provide generic higher-order functions to make it easier to perform Entity actions on Players and Pickups:
overPlayerEntity :: (Entity -> Entity) -> Player -> Player
overPlayerEntity fn (Player pe h) = Player (fn pe) h
overPickupEntity :: (Entity -> Entity) -> Pickup -> Pickup
overPickupEntity fn (Pickup pe t) = Pickup (fn pe) t
Now, we can have
movePlayer = overPlayerEntity move
movePickup = overPickupEntity move
We can also wrap this up into a type class to make it easier to write generic code as well:
class HasEntity a where
overEntity :: (Entity -> Entity) -> a -> a
instance HasEntity Player where overEntity = overPlayerEntity
instance HasEntity Pickup where overEntity = overPickupEntity
This allows things like:
move' :: HasEntity a => a -> a
move' = overEntity move
which works with both Players and Pickups. This eliminates the need for a specialized version of functions like move and at the same time we only need to write the Entity access boilerplate once.
Incidentally, this over...Entity way of doing things is approaching the "lens" technique mentioned at the end of #duplode's and #Paul Johnson's answers. These are essentially two (very) specialized lenses. If we add in the HasEntity type class it gives us what might be called a "classy lens" (this is sort of the terminology used in the lens library). You don't really need to worry about what the general lens concept means or entails, but this could give you an entry point to learn about lenses in the future.
You could just use a sum (aka "union") type.
data Entity =
Player {
location :: Vector,
-- etc.
health :: Int }
| Pickup {
location :: Vector,
-- etc.
pickupType :: PickupType}
You can factor this out by just having the sum type hold the data that varies.
This has the advantage that you can have a [Entity], which is something you can't do when all the different variations of Entity are different types (unlike OO languages).
Depending on your game model you might also want to separate the location and velocity data from the rest of the player information. Could that data be better held in some kind of spatial data structure like a quadtree? That way you can keep the constant data separate from the stuff that changes with every frame.
One thing you ought to look at are lenses, which exist to solve the problem you describe with lots of getters and setters.
This is more of a long comment than an answer, as the core of what I was going to write is covered well enough by ThreeFx's answer.
Firstly, avoid using OOP jargon, as it will lead to confusion. In your attempt #1, Entity is a data type, not a class, and it is not abstract either. The relationship between Player and Entity in attempt #1 is merely one of composition: a Player has an Entity, and it is not in any way an instance of Entity.
Secondly, record update syntax is quite ugly in Haskell. That doesn't make it complicated, just a little cumbersome. So when you say e.g. "Hard to get or set Entity-implemented fields of an instance", it is not actually hard, just not too pretty. That is not a serious enough concern to determine the design of your data types.
Thirdly, lenses are a way of (among many other things) avoiding the ugliness of the record update syntax. You probably won't want to dive into that right now (wait at least until you have finished your assignment), but I can't resist leaving a link to a highly relevant tutorial for you to read at some point in the future: Program imperatively using Haskell lenses.

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.

how can I add an unboxed array to a Haskell record?

I want to do write some monte-carlo simulations. Because of the nature of simulation, I'll get much better performance if I use mutable state. I think that unboxed mutable arrays are the way to go. There's a bunch of items I'll want to keep track of, so I've created a record type to hold the state.
import Control.Monad.State
import Data.Array.ST
data Board = Board {
x :: Int
, y :: Int
,board :: STUArray (Int,Int) Int
} deriving Show
b = Board {
x = 5
,y = 5
,board = newArray ((1,1),(10,10)) 37 :: STUArray (Int,Int) Int
}
growBoard :: State Board Int
growBoard = do s <- get
let xo = x s
yo = y s in
put s{x=xo*2, y=yo*2}
return (1)
main = print $ runState growBoard b
If I leave out the "board" field from the record, everything else works fine. But with it, I get a type error:
`STUArray (Int, Int) Int' is not applied to enough type arguments
Expected kind `?', but `STUArray (Int, Int) Int' has kind `* -> *'
In the type `STUArray (Int, Int) Int'
In the definition of data constructor `Board'
In the data type declaration for `Board'
I've read through the Array page, and I can get STUArray examples working. But as soon as I try to add one to my State record, I get the error about the unexpected kind. I'm guessing I need a monad transformer of some kind, but I don't know where to start.
How should I declare an unboxed array inside a record? How should I initialize it?
I see alot of example of unboxed STArray, but they're mostly program fragments, so I feel like I'm missing context.
Also, where can I learn more about "kinds"? I know kinds are "type types" but the abstract nature of that is making it hard to grasp.
STUArray is a mutable array, designed to be used internally from within the ST monad to implement externally-pure code. Just like STRef and all the other structures used in the ST monad, STUArray takes an additional parameter representing a state thread.
The kind error you're getting is simply telling you missed an argument: at the value level, you might get an error "expected b but got a -> b" to tell you you missed an argument; at the type level, it looks like "expected ? but got * -> *", where * represents a plain, "fully-applied" type (like Int). (You can pretend ? is the same as *; it's just there to support unboxed types, which are a GHC-specific implementation detail.)
Basically, you can think of kinds as coming in two shapes:
*, representing a concrete type, like Int, Double, or [(Float, String)];
k -> l, where k and l are both kinds, representing a type constructor, like Tree, [], IO, and STUArray. Such a type constructor takes a type of kind k, and returns a type of kind l.
If you want to use ST arrays, you'll need to add a type parameter to Board:
data Board s = Board {
x :: Int
, y :: Int
,board :: STUArray s (Int,Int) Int
} deriving Show
and use StateT (Board s) (ST s) as your monad rather than just State Board.
However, I don't see any reason to use ST or mutable structures in general here, and I would instead suggest using a simple immutable array, and mutating it in the same way as the rest of your state, with the State monad:
data Board = Board {
x :: Int
, y :: Int
,board :: UArray (Int,Int) Int
} deriving Show
(using Data.Array.Unboxed.UArray)
This can be "modified" just like any other element of your record, by transforming it with the pure functions from the immutable array interface.

Resources