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

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.

Related

Haskell: Show instance of IOArray

I'm learning Haskell and trying to use mutable arrays (in particular IOArray). I wrote a pretty printer that has the following type:
disp :: Show a => IOArray Int a -> IO String
I didn't manage to get rid of the IO part because of a subcall to
getBounds :: Ix i => a i e -> m (i, i)
Now I'm trying to use disp to define a Show instance for my IOArray type but the IO gets in the way.
Is it possible to create a Show instance for IOArray ?
An IOArray is not really an array. It's just a reference to an array. Absolutely everything interesting you can do with an IOArray produces an action in IO. Why is that? Suppose you could index into an IOArray in pure code:
(!) :: IOArray Int a -> a
Consider the following:
f :: IO (Char, Char)
f = do
ar <- newArray (0 :: Int, 10 :: Int) 'a'
let x = ar ! 3
writeArray ar 3 'b'
let y = ar ! 3
return (x, y)
What should f produce? One answer might be that it should produce ('a', 'b'), because the third element of ar started out as 'a' and then was changed to 'b'. But that's deeply troubling! How can ar ! 3 have one value at one time and another later? That violates the fundamental idea of referential transparency that purely functional languages are built on. So you just can't do that.
AFAIK in Haskell getting rid of Monads is neither possible nor correct. Some monads (like Maybe and Either) has special methods to unwrap their values, but (over)using them is discouraged. If you have any Haskell type that is wrapped within a Monad context, you must use it and work with it without unwrapping and releasing. For your case, any type within an IO monad, can not be converted (using any type of function like Show) to any type without IO Monad. One solution for your case is using Haskell's rich treasure of Monad functions and operators to convert inner type (e.g. Int) to Char, and after that you have a IO String instead of IOArray, which in turn you can print out.

Haskell type checking in code

Could you please show me how can I check if type of func is Tree or not, in code not in command page?
data Tree = Leaf Float | Gate [Char] Tree Tree deriving (Show, Eq, Ord)
func a = Leaf a
Well, there are a few answers, which zigzag in their answers to "is this possible".
You could ask ghci
ghci> :t func
func :: Float -> Tree
which tells you the type.
But you said in your comment that you are wanting to write
if func == Tree then 0 else 1
which is not possible. In particular, you can't write any function like
isTree :: a -> Bool
isTree x = if x :: Tree then True else False
because it would violate parametericity, which is a neat property that all polymorphic functions in Haskell have, which is explored in the paper Theorems for Free.
But you can write such a function with some simple generic mechanisms that have popped up; essentially, if you want to know the type of something at runtime, it needs to have a Typeable constraint (from the module Data.Typeable). Almost every type is Typeable -- we just use the constraint to indicate the violation of parametericity and to indicate to the compiler that it needs to pass runtime type information.
import Data.Typeable
import Data.Maybe (isJust)
data Tree = Leaf Float | ...
deriving (Typeable) -- we need Trees to be typeable for this to work
isTree :: (Typeable a) => a -> Bool
isTree x = isJust (cast x :: Maybe Tree)
But from my experience, you probably don't actually need to ask this question. In Haskell this question is a lot less necessary than in other languages. But I can't be sure unless I know what you are trying to accomplish by asking.
Here's how to determine what the type of a binding is in Haskell: take something like f a1 a2 a3 ... an = someExpression and turn it into f = \a1 -> \a2 -> \a3 -> ... \an -> someExpression. Then find the type of the expression on the right hand side.
To find the type of an expression, simply add a SomeType -> for each lambda, where SomeType is whatever the appropriate type of the bound variable is. Then use the known types in the remaining (lambda-less) expression to find its actual type.
For your example: func a = Leaf a turns into func = \a -> Leaf a. Now to find the type of \a -> Leaf a, we add a SomeType -> for the lambda, where SomeType is Float in this case. (because Leaf :: Float -> Tree, so if Leaf is applied to a, then a :: Float) This gives us Float -> ???
Now we find the type of the lambda-less expression Leaf (a :: Float), which is Tree because Leaf :: Float -> Tree. Now we can add substitute Tree for ??? to get Float -> Tree, the actual type of func.
As you can see, we did that all by just looking at the source code. This means that no matter what, func will always have that type, so there is no need to check whether or not it does. In fact, the compiler will throw out all information about the type of func when it compiles your code, and your code will still work properly because of type-checking. (The caveat to this (Typeable) is pointed out in the other answer)
TL;DR: Haskell is statically typed, so func always has the type Float -> Tree, so asking how to check whether that is true doesn't make sense.

New type declaring functions?

I'm familiar with the newtype declaration:
newtype MyAge = Age {age :: Int} deriving (Show, Eq, Ord)
In this instance Age is an Int, however I've come across the code below and I can't understand it:
newtype Ages a = Ages {age :: String -> [(a,String)]}
This appears to be a function declaration? (takes string, returns list of tuples containing 'a' and string) - is this correct?
N.B I've just realized this is just basic record syntax to declare a function.
Additionally, I've tried to implement this type, but I must be doing something wrong:
newtype Example a = Example {ex :: Int -> Int}
myexample = Example {ex = (\x -> x + 1)}
This compiles, however I don't understand why as I haven't passed the 'a' parameter?
This appears to be a function declaration?
Yes. Specifically, String -> [(a,String)] is a function type. A newtype declaration is analogous to a simple wrapper around any given type. There's no restriction that says you can't make it based on a function type, and it works in exactly the same way.
Also remember that you can always replace newtype with data; in this case, thinking about the resulting type as a record type that has a field that is a function might be helpful; newtype is just a special, optimized case.
One other thing to mention is that your two lines also differ in that the second one is parametrized over a. This can of course be used with regular types:
newtype MyWrapper a = MyWrapper a
or a function type can be newtype-d without parametrisation
newtype MyFunction = MyFunction (Float -> Float)
You can also write the above using the record syntax that gives you the "getter" function as well.

How to store arbitrary values in a recursive structure or how to build a extensible software architecture?

I'm working on a basic UI toolkit and am trying to figure out the overall architecture.
I am considering to use WAI's structure for extensibility. A reduced example of the core structure for my UI:
run :: Application -> IO ()
type Application = Event -> UI -> (Picture, UI)
type Middleware = Application -> Application
In WAI, arbitrary values for Middleware are saved in the vault. I think that this is a bad hack to save arbitary values, because it isn't transparent, but I can't think of a sufficient simple structure to replace this vault to give every Middleware a place to save arbitrary values.
I considered to recursively store tuples in tuples:
run :: (Application, x) -> IO ()
type Application = Event -> UI -> (Picture, UI)
type Middleware y x = (Application, x) -> (Application, (y,x))
Or to only use lazy lists to provide a level on which is no need to separate values (which provides more freedom, but also has more problems):
run :: Application -> IO ()
type Application = [Event -> UI -> (Picture, UI)]
type Middleware = Application -> Application
Actually, I would use a modified lazy list solution. Which other solutions might work?
Note that:
I prefer not to use lens at all.
I know UI -> (Picture, UI) could be defined as State UI Picture .
I'm not aware of a solution regarding monads, transformers or FRP. It would be great to see one.
Lenses provide a general way to reference data type fields so that you can extend or refactor your data set without breaking backwards compatibility. I'll use the lens-family and lens-family-th libraries to illustrate this, since they are lighter dependencies than lens.
Let's begin with a simple record with two fields:
{-# LANGUAGE Template Haskell #-}
import Lens.Family2
import Lens.Family2.TH
data Example = Example
{ _int :: Int
, _str :: String
}
makeLenses ''Example
-- This creates these lenses:
int :: Lens' Example Int
str :: Lens' Example String
Now you can write Stateful code that references fields of your data structure. You can use Lens.Family2.State.Strict for this purpose:
import Lens.Family2.State.Strict
-- Everything here also works for `StateT Example IO`
example :: State Example Bool
example = do
s <- use str -- Read the `String`
str .= s ++ "!" -- Set the `String`
int += 2 -- Modify the `Int`
zoom int $ do -- This sub-`do` block has type: `State Int Int`
m <- get
return (m + 1)
The key thing to note is that I can update my data type, and the above code will still compile. Add a new field to Example and everything will still work:
data Example = Example
{ _int :: Int
, _str :: String
, _char :: Char
}
makeLenses ''Example
int :: Lens' Example Int
str :: Lens' Example String
char :: Lens' Example Char
However, we can actually go a step further and completely refactor our Example type like this:
data Example = Example
{ _example2 :: Example
, _char :: Char
}
data Example2 = Example2
{ _int2 :: Int
, _str2 :: String
}
makeLenses ''Example
char :: Lens' Example Char
example2 :: Lens' Example Example2
makeLenses ''Example2
int2 :: Lens' Example2 Int
str2 :: Lens' Example2 String
Do we have to break our old code? No! All we have to do is add the following two lenses to support backwards compatibility:
int :: Lens' Example Int
int = example2 . int2
str :: Lens' Example Char
str = example2 . str2
Now all the old code still works without any changes, despite the intrusive refactoring of our Example type.
In fact, this works for more than just records. You can do the exact same thing for sum types, too (a.k.a. algebraic data types or enums). For example, suppose we have this type:
data Example3 = A String | B Int
makeTraversals ''Example3
-- This creates these `Traversals'`:
_A :: Traversal' Example3 String
_B :: Traversal' Example3 Int
Many of the things that we did with sum types can similarly be re-expressed in terms of Traversal's. There's a notable exception of pattern matching: it's actually possible to implement pattern matching with totality checking with Traversals, but it's currently verbose.
However, the same point holds: if you express all your sum type operations in terms of Traversal's, then you can greatly refactor your sum type and just update the appropriate Traversal's to preserve backwards compatibility.
Finally: note that the true analog of sum type constructors are Prisms (which let you build values using the constructors in addition to pattern matching). Those are not supported by the lens-family family of libraries, but they are provided by lens and you can implement them yourself using just a profunctors dependency if you want.
Also, if you're wondering what the lens analog of a newtype is, it's an Iso', and that also minimally requires a profunctors dependency.
Also, everything I've said works for reference multiple fields of recursive types (using Folds). Literally anything you can imagine wanting to reference in a data type in a backwards-compatible way is encompassed by the lens library.

Why does Haskell not have records with structural typing?

I have heard Haskell described as having structural typing. Records are an exception to that though as I understand. For example foo cannot be called with something of type HRec2 even though HRec and HRec2 are only nominally different in their fields.
data HRec = HRec { x :: Int, y :: Bool }
data HRec2 = HRec2 { p :: Int, q :: Bool }
foo :: HRec -> Bool
Is there some explanation for rejecting extending structural typing to everything including records?
Are there statically typed languages with structural typing even for records? Is there maybe some debate on this I can read about for all statically typed languages in general?
Haskell has structured types, but not structural typing, and that's not likely to change.*
The refusal to permit nominally different but structurally similar types as interchangeable arguments is called type safety. It's a good thing. Haskell even has a newtype declaration to provide types which are only nominally different, to allow you to enforce more type safety. Type safety is an easy way to catch bugs early rather than permit them at runtime.
In addition to amindfv's good answer which includes ad hoc polymorphism via typeclasses (effectively a programmer-declared feature equivalence), there's parametric polymorphism where you allow absolutely any type, so [a] allows any type in your list and BTree a allows any type in your binary tree.
This gives three answers to "are these types interchangeable?".
No; the programmer didn't say so.
Equivalent for a specific purpose because the programmer said so.
Don't care - I can do the same thing to this collection of data because it doesn't use any property of the data itself.
There's no 4: compiler overrules programmer because they happened to use a couple of Ints and a String like in that other function.
*I said Haskell is unlikely to change to structural typing. There is some discussion to introduce some form of extensible records, but no plans to make (Int,(Int,Int)) count as the same as (Int, Int, Int) or Triple {one::Int, two::Int, three::Int} the same as Triple2 {one2::Int, two2::Int, three2::Int}.
Haskell records aren't really "less structural" than the rest of the type system. Every type is either completely specified, or "specifically vague" (i.e. defined with a typeclass).
To allow both HRec and HRec2 to f, you have a couple of options:
Algebraic types:
Here, you define HRec and HRec2 records to both be part of the HRec type:
data HRec = HRec { x :: Int, y :: Bool }
| HRec2 { p :: Int, q :: Bool }
foo :: HRec -> Bool
(alternately, and maybe more idiomatic:)
data HRecType = Type1 | Type2
data HRec = HRec { hRecType :: HRecType, x :: Int, y :: Bool }
Typeclasses
Here, you define foo as able to accept any type as input, as long as a typeclass instance has been written for that type:
data HRec = HRec { x :: Int, y :: Bool }
data HRec2 = HRec2 { p :: Int, q :: Bool }
class Flexible a where
foo :: a -> Bool
instance Flexible HRec where
foo (HRec a _) = a == 5 -- or whatever
instance Flexible HRec2 where
foo (HRec2 a _) = a == 5
Using typeclasses allows you to go further than regular structural typing -- you can accept types that have the necessary information embedded in them, even if the types don't superficially look similar, e.g.:
data Foo = Foo { a :: String, b :: Float }
data Bar = Bar { c :: String, d :: Integer }
class Thing a where
doAThing :: a -> Bool
instance Thing Foo where
doAThing (Foo x y) = (x == "hi") && (y == 0)
instance Thing Bar where
doAThing (Bar x y) = (x == "hi") && ((fromInteger y) == 0)
We can run fromInteger (or any arbitrary function) to get the data we need from what we have!
I'm aware of two library implementations of structurally typed records in Haskell:
HList is older, and is explained in an excellent paper: Haskell's overlooked object system (free online, but SO won't let me include more links)
vinyl is newer, and uses fancy new GHC features. There's at least one library, vinyl-gl, using it.
I cannot answer the language-design part of your question, though.
To answer your last question, Go and Scalas definitely have structural typing. Some people (including me) would call that "statically unsafe typing", since it implicitly declares all samely- named methods in a program to have the same semantics, which implies "spooky action at a distance", relating code in on source file to code in some library that the program has never seen.
IMO, better to require that the same-named methods to explicitly declare that they conform to a named semantic "model" of behavior.
Yes, the compiler would guarantee that the method is callable, but it isn't much safer than saying:
f :: [a] -> Int
And letting the compiler choose an arbitrary implementation that may or may not be length.
(A similar idea can be made safe with Scala "implicits" or Haskell (GHC?) "reflection" package.)

Resources