I'm trying to apply a function to a Matrix but I don't know how to proceed.
Here's how I define my Matrix :
data Matrice a = Mat [[a]]
montre [] = "/"
montre (t:q) = "" ++ (Pp.printf "%5s" (show t)) ++ " " ++ (montre q)
instance (Show a) => Show (Matrice a) where
show (Mat ([])) = ""
show (Mat (t:q)) = "/" ++ (montre t) ++ "\n" ++ (show (Mat q))
Then, once my Matrix is defined I'd like to apply my function z95 to each of the elements of the matrix.
Here's the signature of my z95 function (which allows to convert a integer into this integer modulo 95)
z95 n = Z95(n %% 95)
z95 18 = 18%95
I tried to do a double map too access the elements of my Matrix but then I didn't figure out how to apply my z95 function.
Thanks fo the help!
You could define a Functor instance for your type, which is the usual way to map a function over the elements of a container.
instance Functor Matrice where
fmap f (Mat xss) = Mat (map (map f) xss)
Now you can write
>> let m = Mat [[1,2,3],[4,5,6]]
>> fmap (+3) m -- => Mat [[4,5,6],[7,8,9]]
or in your case
>> fmap z95 m
Related
I've started programming in haskell like 2 months ago, im fairly new so don't expect me to be some top tier expect at monads or whatever please. I have tried in so many ways to get this Forest dataType be instance of functor and show, but i really don't know how to solve the conflicts that the compiler is giving to me. Such as:
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
|
15 | show ((Tree a) : (Forest s) ) = "[" ++ show a ++ "," ++ show s ++ "]"
| ^^^^
exercici3.hs:15:23: error: Not in scope: data constructor ‘Forest’
|
15 | show ((Tree a) : (Forest s) ) = "[" ++ show a ++ "," ++ show s ++ "]"
| ^^^^^^
exercici3.hs:19:12: error:
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
|
19 | fmap ((Tree a) : (Forest s)) = [f a] ++ (fmap f s)
| ^^^^
exercici3.hs:19:23: error: Not in scope: data constructor ‘Forest’
|
19 | fmap ((Tree a) : (Forest s)) = [f a] ++ (fmap f s)
| ^^^^^^
This is the font code of the classes. I've been thinking for a long time and i can't find a resonable solution, all help is welcome , thank you!
data Tree a = Empty | Node a (Tree a) (Tree a)
data Forest a = Nil | Cons (Tree a) (Forest a)
instance Show a => Show (Tree a) where
show Empty = "()"
show (Node b (xl) (xr)) = "(" ++ show xl ++ "," ++ (show b) ++ "," ++ show xr ++ ")"
instance Functor (Tree ) where
fmap f Empty = Empty
fmap f (Node a (xl) (xr)) = Node (f a) (fmap f xl) (fmap f xr)
instance Show a => Show (Forest a) where
show Nil = []
show ((Tree a) : (Forest s) ) = "[" ++ show a ++ "," ++ show s ++ "]"
instance Functor (Forest) where
fmap f Nil = []
fmap ((Tree a) : (Forest s)) = [f a] ++ (fmap f s)
Just to be clear, the Tree datatype works just fine, its just the syntactic part of the forest that doesnt seem to work at all.
The data constructor is Cons, not (:). Then you use for example x and xs as variables, where x has type Tree a, and xs has type Forest a:
instance Show a => Show (Forest a) where
show Nil = ""
show (Cons x xs) = "[" ++ show x ++ "," ++ show xs ++ "]"
instance Functor Forest where
fmap f Nil = Nil
fmap f (Cons x xs) = Cons (fmap f x) (fmap f xs)
That being said, I don't see much reasons to define a data type Forest here, you can define this as:
type Forest a = [Tree a]
I have a data type and function like this:
data Expr = Num Int | Add Expr Expr | Mult Expr Expr | Neg Expr | If Expr Expr Expr deriving (Show, Read)
prettyPrint :: Expr -> IO ()
prettyPrint expr = prettyPrint' expr 0
prettyPrint' :: Expr -> Int -> IO ()
prettyPrint' (Num x) i = putStrLn $ concat (replicate i " ") ++ "Num " ++ show x
prettyPrint' (Add x y) i = do
putStrLn $ concat (replicate i " ") ++ "Add"
prettyPrint' x (i+1)
prettyPrint' y (i+1)
prettyPrint' (Mult x y) i = do
putStrLn $ concat (replicate i " ") ++ "Mult"
prettyPrint' x (i+1)
prettyPrint' y (i+1)
prettyPrint' (Neg x) i = do
putStrLn $ concat (replicate i " ") ++ "Neg"
prettyPrint' x (i+1)
prettyPrint' (If x y z) i = do
putStrLn $ concat (replicate i " ") ++ "If"
prettyPrint' x (i+1)
prettyPrint' y (i+1)
prettyPrint' z (i+1)
In the function I am using pattern matching. The problem is that their is a lot of reuse of code. For example, the case for Mult and Add is basically the same code. Same goes for Num and Neg. Is there a way to write this based on how many variables the expression have? Like one for Num and Neg, since they have only one variable. One case for Mult and Add, since they have two variables. And a last case for If, since that expression have three variables.
NOTE:
I landed on this answer, I think it's a better solution than I started with:
prettyPrint :: Expr -> IO ()
prettyPrint expr = putStrLn (prettyPrint' 1 expr)
prettyPrint' :: Int -> Expr -> String
prettyPrint' i (Num x) = "Num " ++ show x
prettyPrint' i expr =
let indent x = concat (replicate i " ") ++ x
(op, args) = case expr of
Add x y -> ("Add", [x,y])
Mult x y -> ("Mult", [x,y])
Neg x -> ("Neg", [x])
If x y z -> ("If", [x,y,z])
in intercalate "\n" (op : map (indent . prettyPrint' (i + 1)) args)
First, I would stay out of the IO monad for as long as possible. Have prettyPrint' return a string to be printed.
prettyPrint :: Expr -> IO ()
prettyPrint = putStrLn . prettyPrint'
Now, the only job of prettyPrint' is to create a (possibly multiline) string to be printed. For numbers, that's easy: just use the show instance.
prettyPrint' :: Expr -> String
prettyPrint' e#(Num _) = show e
-- or, ignoring the Show instance for Expr altogether
-- prettyPrint' (Num x) = "Num " ++ show x
For the rest, there is a pattern:
Identify the constructor
Identify its arguments
Join the constructor name and its pretty-printed arguments with newlines. Each argument will be indented one level relative to its operator; the recursion will take care of multiple levels of indentation.
That will look like
prettyPrint' expr = let indent x = " " ++ x
(op, args) = case expr of
Add x y -> ("Add", [x,y])
Mult x y -> ("Mult", [x,y])
Neg x -> ("Neg", [x])
If x y z -> ("If", [x,y,z])
in intercalate "\n" (op : map (indent . prettyPrint') args)
As an example, consider what prettyPrint' will do with the expression Add (Num 3) (Num 5). First, it sets op to "Add" and args to [Num 3, Num 5]. Next, it maps indent . prettyPrint' over the argument list, to get [" Num 3", " Num 5"]. Putting the operator on the front of the list yields ["Add", " Num 3", " Num 3"], then joining them with intercalate produces "Add\n Num 3\n Num 5".
The only remaining boilerplate is in the case expression. I think it's possible to eliminate that, but it requires a level of generic programming I'm not familiar with. I'm sure someone else could probably run with my answer to fix that.
In general, when addressing duplication in code, it pays to keep the rule of three in mind. Two occurrences of a block of code isn't necessarily a problem.
That said, Haskell is a (very) strongly-typed language, so you generally can't pattern-match on arity like you can in, say, Erlang or Clojure.
If you really want to abstract away the recursion part of a recursive data structure, you can define the catamorphism for it. People often also call this a fold, so let's keep that slightly more friendly name:
data Expr =
Num Int | Add Expr Expr | Mult Expr Expr | Neg Expr | If Bool Expr Expr deriving (Show, Read)
foldExpr ::
(Int -> a) -> (a -> a -> a) -> (a -> a -> a) -> (a -> a) -> (Bool -> a -> a -> a) -> Expr -> a
foldExpr num _ _ _ _ (Num x) = num x
foldExpr num add mul neg iff (Add x y) =
add (foldExpr num add mul neg iff x) (foldExpr num add mul neg iff y)
foldExpr num add mul neg iff (Mult x y) =
mul (foldExpr num add mul neg iff x) (foldExpr num add mul neg iff y)
foldExpr num add mul neg iff (Neg x) = neg (foldExpr num add mul neg iff x)
foldExpr num add mul neg iff (If b x y) =
iff b (foldExpr num add mul neg iff x) (foldExpr num add mul neg iff y)
This is an entirely generic function that enables you turn turn any Expr value into any value of the type a, without worrying about reimplementing recursion every time. You just have to supply functions that deal with each of the cases.
You can, for example, easily write an evaluator:
evaluate :: Expr -> Int
evaluate = foldExpr id (+) (*) negate (\p x y -> if p then x else y)
(Notice, BTW, that I changed the definition of If, because I couldn't see how the OP definition would work.)
You can also write a function to turn an Expr value into a string, although this one is just a sketch; it needs indentation or bracket logic to work correctly:
prettyPrint :: Expr -> String
prettyPrint =
foldExpr
show -- Num
(\x y -> x ++ "+" ++ y) -- Add
(\x y -> x ++ "*" ++ y) -- Mult
(\x -> "(-" ++ x ++ ")") -- Neg
(\p x y -> "if " ++ show p ++ " then " ++ x ++ " else " ++ y) -- If
You can try it out in GHCi:
*Q53284410> evaluate (Num 42)
42
*Q53284410> evaluate (Add (Num 40) (Num 2))
42
*Q53284410> evaluate (Add (Mult (Num 4) (Num 10)) (Num 2))
42
*Q53284410> prettyPrint $ Num 42
"42"
*Q53284410> prettyPrint $ Mult (Num 6) (Num 7)
"6*7"
*Q53284410> prettyPrint $ Add (Mult (Num 2) (Num 3)) (Num 7)
"2*3+7"
Yes, just create a function to print list of Expr:
import Control.Monad (forM_)
printExprList::[Expr]->Int->String->IO ()
printExprList exprs i desc = do
putStrLn $ concat (replicate i " ") ++ desc
forM_ (zip exprs [i..]) $ \(e, j)-> prettyPrint' e (j+1)
and then call it to print:
prettyPrint' :: Expr -> Int -> IO ()
prettyPrint' (Add x y) i = printExprList [x, y] i "Add"
prettyPrint' (Mult x y) i = printExprList [x, y] i "Mult"
prettyPrint' (Neg x) i = printExprList [x] i "Neg"
prettyPrint' (If x y z) i = printExprList [x, y, z] i "If"
prettyPrint' (Num x) i = putStrLn $ concat (replicate i " ")
++ "Num " ++ show x
I have defined a (Matrix) datatype, as a 2D list:
newtype Matrix a = M [[a]]
and an instance for Show, as follows:
instance Show a => Show (Matrix a) where
show (M a) = intercalate "\n" (map (unwords . map show) a) ++ "\n"
Which behaves like so:
> mat = M [[3,1,8],[6,3,0],[6,8,8]]
> mat
3 1 8
6 3 0
6 8 8
However, I'd like to handle how it prints lists, because the default behaviour looks a bit weird. How do I specify this? I've tried something like these:
instance Show a => Show ([Matrix a]) where
show mat = case mat of
[M a] -> intercalate "\n" (map (unwords . map show) a) ++ "\n"
(m:ms) -> show m ++ "\n" ++ show ms
instance Show a => Show (Matrix a) where
show (M a) = intercalate "\n" (map (unwords . map show) a) ++ "\n"
show (m:ms) = show m ++ "\n" ++ show ms
But I just get syntax errors. I tried googling the issue, but I couldn't find anything (Perhaps I used the wrong keywords?)
Thanks in advance.
EDIT:
Desired input and output:
mat1 = M [[1,2],[3,4]]
mat2 = M [[1,2],[3,4]]
> [mat1, mat2]
1 2
3 4,
1 2
3 4
This is exactly what the showList method is for:
instance Show a => Show (Matrix a) where
show (M a) = intercalate "\n" (map (unwords . map show) a) ++ "\n"
showList (m:ms) = shows m . ("\n" ++) . showList ms
Note that this doesn't handle empty lists, though, so you also need
showList [] = id
(or whatever you want it to show for empty lists.)
List functions allow us to implement arbitrarily-dimensional vector math quite elegantly. For example:
on = (.) . (.)
add = zipWith (+)
sub = zipWith (-)
mul = zipWith (*)
dist = len `on` sub
dot = sum `on` mul
len = sqrt . join dot
And so on.
main = print $ add [1,2,3] [1,1,1] -- [2,3,4]
main = print $ len [1,1,1] -- 1.7320508075688772
main = print $ dot [2,0,0] [2,0,0] -- 4
Of course, this is not the most efficient solution, but is insightful to look at, as one can say map, zipWith and such generalize those vector operations. There is one function I couldn't implement elegantly, though - that is cross products. Since a possible n-dimensional generalization of cross products is the nd matrix determinant, how can I implement matrix multiplication elegantly?
Edit: yes, I asked a completely unrelated question to the problem I set up. Fml.
It just so happens I have some code lying around for doing n-dimensional matrix operations which I thought was quite cute when I wrote it at least:
{-# LANGUAGE NoMonomorphismRestriction #-}
module MultiArray where
import Control.Arrow
import Control.Monad
import Data.Ix
import Data.Maybe
import Data.Array (Array)
import qualified Data.Array as A
-- {{{ from Dmwit.hs
deleteAt n xs = take n xs ++ drop (n + 1) xs
insertAt n x xs = take n xs ++ x : drop n xs
doublify f g xs ys = f (uncurry g) (zip xs ys)
any2 = doublify any
all2 = doublify all
-- }}}
-- makes the most sense when ls and hs have the same length
instance Ix a => Ix [a] where
range = sequence . map range . uncurry zip
inRange = all2 inRange . uncurry zip
rangeSize = product . uncurry (zipWith (curry rangeSize))
index (ls, hs) xs = fst . foldr step (0, 1) $ zip indices sizes where
indices = zipWith index (zip ls hs) xs
sizes = map rangeSize $ zip ls hs
step (i, b) (s, p) = (s + p * i, p * b)
fold :: (Enum i, Ix i) => ([a] -> b) -> Int -> Array [i] a -> Array [i] b
fold f n a = A.array newBound assocs where
(oldLowBound, oldHighBound) = A.bounds a
(newLowBoundBeg , dimLow : newLowBoundEnd ) = splitAt n oldLowBound
(newHighBoundBeg, dimHigh: newHighBoundEnd) = splitAt n oldHighBound
assocs = [(beg ++ end, f [a A.! (beg ++ i : end) | i <- [dimLow..dimHigh]])
| beg <- range (newLowBoundBeg, newHighBoundBeg)
, end <- range (newLowBoundEnd, newHighBoundEnd)
]
newBound = (newLowBoundBeg ++ newLowBoundEnd, newHighBoundBeg ++ newHighBoundEnd)
flatten a = check a >> return value where
check = guard . (1==) . length . fst . A.bounds
value = A.ixmap ((head *** head) . A.bounds $ a) return a
elementWise :: (MonadPlus m, Ix i) => (a -> b -> c) -> Array i a -> Array i b -> m (Array i c)
elementWise f a b = check >> return value where
check = guard $ A.bounds a == A.bounds b
value = A.listArray (A.bounds a) (zipWith f (A.elems a) (A.elems b))
unsafeFlatten a = fromJust $ flatten a
unsafeElementWise f a b = fromJust $ elementWise f a b
matrixMult a b = fold sum 1 $ unsafeElementWise (*) a' b' where
aBounds = (join (***) (!!0)) $ A.bounds a
bBounds = (join (***) (!!1)) $ A.bounds b
a' = copy 2 bBounds a
b' = copy 0 aBounds b
bijection f g a = A.ixmap ((f *** f) . A.bounds $ a) g a
unFlatten = bijection return head
matrixTranspose = bijection reverse reverse
copy n (low, high) a = A.ixmap (newBounds a) (deleteAt n) a where
newBounds = (insertAt n low *** insertAt n high) . A.bounds
The cute bit here is matrixMult, which is one of the only operations that is specialized to two-dimensional arrays. It expands its first argument along one dimension (by putting a copy of the two-dimensional object into each slice of the three-dimensional object); expands its second along another; does pointwise multiplication (now in a three-dimensional array); then collapses the fabricated third dimension by summing. Quite nice.
I have been experimenting with the following Haskell code:
data Foo = Foo
{ fooMin :: Float
, fooMax :: Float
, fooSum :: Float
} deriving Show
getLocalFoo :: [Float] -> Foo
getLocalFoo x = Foo a b c
where
a = minimum x
b = maximum x
c = sum x
getGlobalFoo :: [Foo] -> Foo
getGlobalFoo x = Foo a b c
where
a = minimum $ fmap fooMin x
b = maximum $ fmap fooMax x
c = sum $ fmap fooSum x
main :: IO()
main = do
let numItems = 2000
let numLists = 100000
putStrLn $ "numItems: " ++ show numItems
putStrLn $ "numLists: " ++ show numLists
-- Create an infinite list of lists of floats, x is [[Float]]
let x = take numLists $ repeat [1.0 .. numItems]
-- Print two first elements of each item
print $ take 2 (map (take 2) x)
-- First calculate local min/max/sum for each float list
-- then calculate the global min/max/sum based on the results.
print . getGlobalFoo $ fmap getLocalFoo x
And sequentially tested runtime when adjusting numItems and numLists:
Low size:
numItems: 4.0
numLists: 2
[[1.0,2.0],[1.0,2.0]]
Foo {fooMin = 1.0, fooMax = 4.0, fooSum = 20.0}
real 0m0.005s
user 0m0.004s
sys 0m0.001s
High size:
numItems: 2000.0
numLists: 100000
[[1.0,2.0],[1.0,2.0]]
Foo {fooMin = 1.0, fooMax = 2000.0, fooSum = 1.9999036e11}
real 0m33.116s
user 0m33.005s
sys 0m0.109s
I have written this code in a in my opinion intuitive and naive way without consideration to performance, however I am concerned that this is far from optimal code as I may actually be folding through the lists way more times then necessary?
Could anyone suggest a better implementation of this test?
Use the foldl library to run multiple folds efficiently in a single pass. In fact, it's so good at this that you don't need to split your list into sublists. You can just concatenate all the lists together into one giant list and fold that directly.
Here's how:
import Control.Applicative
import qualified Control.Foldl as L
data Foo = Foo
{ fooMin :: Maybe Float
, fooMax :: Maybe Float
, fooSum :: Float
} deriving Show
foldFloats :: L.Fold Float Foo
foldFloats = Foo <$> L.minimum <*> L.maximum <*> L.sum
-- or: foldFloats = liftA3 Foo L.minimum L.maximum L.sum
main :: IO()
main = do
let numItems = 2000
let numLists = 100000
putStrLn $ "numItems: " ++ show numItems
putStrLn $ "numLists: " ++ show numLists
-- Create an infinite list of lists of floats, x is [[Float]]
let x = replicate numLists [1.0 .. numItems]
-- Print two first elements of each item
print $ take 2 (map (take 2) x)
print $ L.fold foldFloats (concat x)
The main differences from your code are:
I use replicate n, which is the same thing as take n . repeat. In fact, that's how replicate is actually defined
I don't bother processing the sublists individually. I just concat them all together and fold that in a single pass.
I use Maybe for the minimum and maximum since I need to handle the case of an empty list.
This code is faster
Here are the numbers:
$ time ./fold
numItems: 2000.0
numLists: 100000
[[1.0,2.0],[1.0,2.0]]
Foo {fooMin = Just 1.0, fooMax = Just 2000.0, fooSum = 3.435974e10}
real 0m5.796s
user 0m5.756s
sys 0m0.024s
foldl is a really small and easy to learn library. You can learn more about it here.
Monoids to the rescue. All your operations - the sum, minimum and maximum - can be all expressed as monoids. For the minimum and maximum we need to wrap it into Option from the semigroups, because we need to represent somehow the minimum and maximum of an empty collection. (An alternative way would be to restrict ourself to non-empty collections, then we could use semigroups instead of monoids.)
Another thing we'll need is to ensure that all computations are forced during each step. For this we declare Foo's instance of NFData, add some missing instances of the monoid types we use, and a helper function that forces values during the folding operation.
import Control.DeepSeq
import qualified Data.Foldable as F
import Data.Semigroup
-- Declare the data type so that each field is a monoid.
data Foo a = Foo
{ fooMin :: Option (Min a)
, fooMax :: Option (Max a)
, fooSum :: Sum a
} deriving Show
-- Make a Monoid instance - just by combining individual fields.
instance (Ord a, Num a) => Monoid (Foo a) where
mempty = Foo mempty mempty mempty
mappend (Foo n1 x1 s1) (Foo n2 x2 s2) = Foo (n1 <> n2) (x1 <> x2) (s1 <> s2)
-- Add missing NFData instances
instance (NFData a) => NFData (Option a) where
rnf (Option x) = rnf x `seq` ()
instance (NFData a) => NFData (Min a) where
rnf (Min x) = rnf x `seq` ()
instance (NFData a) => NFData (Max a) where
rnf (Max x) = rnf x `seq` ()
instance (NFData a) => NFData (Sum a) where
rnf (Sum x) = rnf x `seq` ()
-- Also add an instance for Foo
instance (NFData a) => NFData (Foo a) where
rnf (Foo n x s) = rnf n `seq` rnf x `seq` rnf s `seq` ()
-- Convert a single element into Foo.
locFoo :: a -> Foo a
locFoo x = Foo (return $ Min x) (return $ Max x) (Sum x)
-- A variant of foldMap that uses left fold and forces monoid
-- elements on the way.
foldMap' :: (F.Foldable f, Monoid m, NFData m) => (a -> m) -> f a -> m
foldMap' f = F.foldl' (\m x -> (mappend $!! m) (f x)) mempty
main :: IO()
main = do
let numItems = 2000
let numLists = 100000
putStrLn $ "numItems: " ++ show numItems
putStrLn $ "numLists: " ++ show numLists
-- Create an infinite list of lists of floats, x is [[Float]]
let x = take numLists $ repeat [1.0 .. numItems] :: [[Float]]
-- Print two first elements of each item
print $ take 2 (map (take 2) x)
-- First calculate local min/max/sum for each float list
-- then calculate the global min/max/sum based on the results.
print . foldMap' (foldMap' locFoo) $ x
Maybe a single fold is cheaper. Try running some tests with something like:
{-# LANGUAGE BangPatterns #-}
import Data.List
getLocalFoo :: [Float] -> Foo
getLocalFoo [] = error "getLocalFoo: empty list"
getLocalFoo (x:xs) = foldl' f (Foo x x x) xs
where f (Foo !min1 !max1 !sum1) y =
Foo (min1 `min` y) (max1 `max` y) (sum1 + y)
and its analogous for getGlobalFoo.