changeset 15:c599d2236d19

Similar as Monad
author Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp>
date Sat, 06 Sep 2014 16:01:27 +0900
parents 116131b196bb
children 4b315cf0edb9
files similar.hs
diffstat 1 files changed, 44 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/similar.hs	Sat Sep 06 11:45:32 2014 +0900
+++ b/similar.hs	Sat Sep 06 16:01:27 2014 +0900
@@ -7,22 +7,30 @@
 same (Single x)    = x
 same (Similar x s) = if x == (same s) then x else (error "same")
 
+value :: Similar a -> a
+value (Single x)    = x
+value (Similar x s) = value s
+
+toList :: Similar a -> [a]
+toList (Single x)      = [x]
+toList (Similar x s) = x : (toList s)
+
+toSimilar :: [a] -> Similar a
+toSimilar []   = undefined
+toSimilar (x:[]) = Single x
+toSimilar (x:xs) = Similar x (toSimilar xs)
 
 instance Functor Similar where
    fmap f (Single a)    = Single (f a)
    fmap f (Similar a s) = Similar (f a) (fmap f s)
 
-mu :: (Eq a) => (Similar (Similar a)) -> Similar a
-mu (Single x)                 = x
-mu (Similar (Single x) s)     = Similar x (mu s)
-mu (Similar s ss) = Similar (same s) (mu ss)
+mu :: (Similar (Similar a)) -> Similar a
+mu s =  toSimilar $ concat $ toList $ fmap (toList) s
 
-{-
 instance Monad Similar where
     return              = Single
     (Single x)    >>= f = f x
     (Similar x s) >>= f = mu $ Similar (f x) (fmap f s)
--}
 
 
 
@@ -38,13 +46,37 @@
 -- samples
 
 {-
-*Main> same $ Main.return 100 Main.>>= (\x -> Similar x twicePlus  $ double x)
-200
+- Similar as Functor
+*Main> fmap (double ) (Single 1)
+Single (Single 2)
+*Main> fmap (twicePlus) (Single 1)
+Single (Similar 2 (Single 2))
+*Main> fmap (plusTwo) (Single 1)
+Single (Similar 3 (Single 2))
+*Main> fmap (fmap double)  (fmap (plusTwo   ) (Single 1))
+Single (Similar (Single 6) (Single (Single 4)))
+*Main> same $ fmap same $ fmap (fmap double)  (fmap (plusTwo   ) (Single 1))
+*** Exception: same
+*Main> same $ fmap same $ fmap (fmap double)  (fmap (plusTwo   ) (Single 2))
+Single 8
 
-*Main> same $ Main.return 2 Main.>>= (\x -> Similar x plusTwo $ double x)
-4
+- Similar as Monad
+*Main>  return 100 >>= double  >>= twicePlus
+Similar 400 (Single 400)
+*Main>  return 100 >>= double  >>= twicePlus >>= plusTwo
+Similar 402 (Similar 800 (Similar 402 (Single 800)))
 
-*Main> same $ Main.return 100 Main.>>= (\x -> Similar x plusTwo $ double x)
-*** Exception: Prelude.undefined
+*Main> same $  return 100 >>= double  >>= twicePlus >>= plusTwo
+*** Exception: same
+*Main> same $  return 100 >>= double  >>= twicePlus
+400
+
+*Main> same $  return 100 >>= double  >>= twicePlus
+400
+*Main> same $  return 100 >>= double  >>= twicePlus >>= plusTwo 
+*** Exception: same
+*Main> value  $  return 100 >>= double  >>= twicePlus >>= plusTwo 
+800
+
 -}