icyrock.com
HomePureScript experiments - matrices
2017-Mar-31 20:34
Here is a small module that can be used for representing matrices.
To start, this module depends on Ex.String module for padLeft:
1 2 3 4 5 6 7 8 | module Ex . String where import Prelude import Data . Array ( replicate ) import Data . String (fromCharArray, length ) padLeft :: Char - > Int - > String - > String padLeft c l s = fromCharArray ( replicate (l - length s) c) <> s |
Let us look at Ex.Mat module itself. These are the imports we will use:
1 2 3 4 5 6 7 8 9 10 | module Ex . Mat where import Prelude import Data . Array (foldM, replicate , updateAt, ( !! )) import Data . Maybe ( Maybe , fromJust) import Data . String (joinWith) import Data . Tuple ( Tuple ( .. )) import Partial . Unsafe ( unsafePartial ) import Ex . String (padLeft) |
Types of matrix, dimension and cell point, with Show instances:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | newtype Mat a = Mat ( Array ( Array a)) instance showMat :: Show a = > Show (Mat a) where show (Mat m) = joinWith "\n" ( map (srow >>> joinWith " " ) m) where srow = map ( show >>> padLeft ' ' 3 ) newtype Dim = Dim { w :: Int , h :: Int } instance showDim :: Show Dim where show (Dim {w, h}) = "[" <> show w <> "x" <> show h <> "]" newtype Pt = Pt { x :: Int , y :: Int } instance showPt :: Show Pt where show (Pt {x, y}) = "(" <> show x <> "," <> show y <> ")" |
A few useful functions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | makeMat :: forall a . Dim - > a - > Mat a makeMat (Dim {w, h}) v = Mat $ replicate h row where row = replicate w v putAt :: forall a . Pt - > a - > Mat a - > Maybe (Mat a) putAt (Pt {x, y}) v (Mat m) = do r < - m !! y nr < - updateAt x v r nm < - updateAt y nr m pure $ Mat nm putMany :: forall a . Array ( Tuple Pt a) - > Mat a - > Maybe (Mat a) putMany ps m = foldM f m ps where f a ( Tuple p v) = putAt p v a |
Finally, a couple of usage examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | p1 :: Mat Int p1 = makeMat (Dim {w : 4 , h : 3 }) 0 p2m :: Maybe (Mat Int ) p2m = putMany [ Tuple (Pt {x : 0 , y : 0 }) 1 , Tuple (Pt {x : 1 , y : 0 }) 2 , Tuple (Pt {x : 2 , y : 0 }) 3 , Tuple (Pt {x : 3 , y : 0 }) 4 , Tuple (Pt {x : 3 , y : 1 }) 5 , Tuple (Pt {x : 3 , y : 2 }) 6 , Tuple (Pt {x : 2 , y : 2 }) 7 , Tuple (Pt {x : 1 , y : 2 }) 8 , Tuple (Pt {x : 0 , y : 2 }) 9 , Tuple (Pt {x : 0 , y : 1 }) 10 , Tuple (Pt {x : 1 , y : 1 }) 11 , Tuple (Pt {x : 2 , y : 1 }) 12 ] p1 p2 :: Mat Int p2 = unsafePartial fromJust p2m |
Creating a matrix with certain dimensions and same value in all cells:
1 2 3 4 5 | > import Ex . Mat > p1 0 0 0 0 0 0 0 0 0 0 0 0 |
Creating a matrix from (point, value) tuples:
1 2 3 4 5 | > import Ex . Mat > p2 1 2 3 4 10 11 12 5 9 8 7 6 |