Skip to content

Instantly share code, notes, and snippets.

@akiradeveloper
Created August 9, 2011 02:58
Show Gist options
  • Save akiradeveloper/1133308 to your computer and use it in GitHub Desktop.
Save akiradeveloper/1133308 to your computer and use it in GitHub Desktop.
While Functor prototype failure
newtype While a = While { get :: (a, Bool) }
instance Functor While where
fmap f (While (a, True)) = let (a', b) = f a in While (a', b)
fmap _ (While (a, False)) = While (a, False)
countDown :: Int -> (Int, Bool)
countDown i =
let i' = i - 1
in
if i' < 0 then (i, False) else (i', True)
main = do
let result = get $ While (1, True) `fmap` countDown `fmap` countDown
print result
@md2perpe
Copy link

md2perpe commented Aug 9, 2011

The boolean value isn't really used. This is practically just Identity monad.

BTW, you can change the implementation of coundDown to:

countDown :: Int -> While Int
countDown i = do
  let i' = i - 1
  While (i, i' >= 0)

which can be even simplified to

countDown :: Int -> While Int
countDown i = While (i, i >= 1)

Could you explain what you are trying to do?

@akiradeveloper
Copy link
Author

Thanks.
One, You are right! This is definitely Identity monad.
Two, You may be wrong. Your countDown implementations are not the same as mine because my version returns While monad with i' if the condition is True whereas with i if False. The difference is your version always returns with i.

@md2perpe
Copy link

md2perpe commented Aug 9, 2011

You're right. I didn't notice the ' after one of the i:s.

You could however write

While $ if i' < 0 
  then (i, False)
  else (i', True)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment