1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import Control.Monad (forM_)
import Data.Maybe (fromMaybe)

mkSound :: Int -> String -> Int -> Maybe String
mkSound m sound n = if n `mod` m == 0 then Just sound else Nothing

fizz, buzz :: Int -> Maybe String
fizz = mkSound 3 "Fizz"
buzz = mkSound 5 "Buzz"

appendMaybe :: Maybe String -> String -> Maybe String -> Maybe String
appendMaybe x _ Nothing = x
appendMaybe Nothing _ y = y
appendMaybe (Just x) sep (Just y) = Just (x <> sep <> y)

fizzBuzz :: IO ()
fizzBuzz = forM_ [1..100] fb
  where
    fb = (putStrLn ∘) ∘ (fromMaybe ∘ show)
      <*> (flip appendMaybe " " ∘ fizz <*> buzz)




--- compiler errors below
[1 of 2] Compiling Main             ( fb1.hs, fb1.o )

fb1.hs:19:11: error:
    Variable not in scope: (∘) :: (String -> IO ()) -> t0
   |
19 |     fb = (putStrLn ∘) ∘ (fromMaybe ∘ show)
   |           ^^^^^^^^^^

fb1.hs:19:23: error: Variable not in scope: (∘) :: t0 -> f0 b1 -> t
   |
19 |     fb = (putStrLn ∘) ∘ (fromMaybe ∘ show)
   |                       ^

fb1.hs:19:36: error:
    Variable not in scope:
      (∘) :: (a1 -> Maybe a1 -> a1) -> (a2 -> String) -> f0 (a3 -> b1)
   |
19 |     fb = (putStrLn ∘) ∘ (fromMaybe ∘ show)
   |                                    ^

fb1.hs:20:33: error:
    Variable not in scope:
      (∘)
        :: (Maybe String -> Maybe String -> Maybe String)
           -> (Int -> b0) -> f0 a3
   |
20 |       <*> (flip appendMaybe " " ∘ fizz <*> buzz)