ekmett / comonad

Haskell 98 comonads
http://hackage.haskell.org/package/comonad
Other
77 stars 32 forks source link

Cokleisli is not a conforming ArrowChoice. #36

Open Zemyla opened 8 years ago

Zemyla commented 8 years ago
import Control.Comonad
import Control.Arrow
import Data.List.NonEmpty (NonEmpty(..))

f :: (Comonad w) => Cokleisli w a (w a)
f = Cokleisli id

arg :: NonEmpty Int
arg = 1 :| [2, 3, 4]

main :: IO ()
main = do
    putStrLn "f >>> arr Left:"
    print $ runCokleisli (f >>> arr Left) arg
    putStrLn "arr Left >>> left f:"
    print $ runCokleisli (arr Left >>> left f) arg

-- f >>> arr Left:
-- Left (1 :| [2,3,4])
-- arr Left >>> arr f:
-- Left (1 :| [1,1,1])

So is there a definition of ArrowChoice for Cokleisli that satisfies the laws?

EDIT: It appears that it breaks an ArrowApply law, too:

GHCi> extend (runCokleisli $ first (arr (>>> f)) >>> app) ((f, 5):|[(Cokleisli (extend product), 8),(Cokleisli (\(a:|ls) -> a:|(3:ls)), 2), (Cokleisli (\(a:|ls) -> case ls of { [] -> a:|[]; b:ls' -> b:|(ls >>= replicate a) }), 4)])
((5 :| [8,2,4]) :| [8 :| [2,4],2 :| [4],4 :| []]) :| [(64 :| [8,4]) :| [8 :| [4],4 :| []],(2 :| [3,4]) :| [4 :| [3]],(4 :| []) :| []]
it :: NonEmpty (NonEmpty (NonEmpty Int))
(0.03 secs, 209,752 bytes)
GHCi> extend (runCokleisli $ app >>> f) ((f, 5):|[(Cokleisli (extend product), 8),(Cokleisli (\(a:|ls) -> a:|(3:ls)), 2), (Cokleisli (\(a:|ls) -> case ls of { [] -> a:|[]; b:ls' -> b:|(ls >>= replicate a) }), 4)])
((5 :| [8,2,4]) :| [64 :| [8,4],2 :| [3,4],4 :| []]) :| [(64 :| [8,4]) :| [2 :| [3,4],4 :| []],(2 :| [3,4]) :| [4 :| []],(4 :| []) :| []]
it :: NonEmpty (NonEmpty (NonEmpty Int))

So that's probably why setting left = leftApp didn't work.