other-languages

here be heresies and things we have to use for work
borkdude 2018-07-25T19:21:50.000396Z

Is anyone here by any chance doing the exercises from HaskellBook? I need a hint on assignment S from chapter 21

2018-07-25T19:45:29.000444Z

I don’t know much about that book but can you paste the problem in here? Or, go to #haskell on freenode…

borkdude 2018-07-25T19:50:28.000405Z

@ddellacosta I need to write a Traversable instance for data S n a = S (n a) a deriving (Eq, Show). This is the code I have:

{-# LANGUAGE FlexibleContexts #-}

module TraversableS where

import Test.QuickCheck hiding (Success, Failure)
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
import Data.Monoid

data S n a = S (n a) a deriving (Eq, Show)

instance ( Functor n
         , Arbitrary (n a)
         , Arbitrary a )
         => Arbitrary (S n a) where
  arbitrary =
    S <$> arbitrary <*> arbitrary

instance ( Applicative n
         , Testable (n Property)
         , EqProp a )
  => EqProp (S n a) where
  (S x y) =-= (S p q) =
    (property $ (=-=) <$> x <*> p)
    .&. (y =-= q)

instance (Functor n) => Functor (S n) where
  fmap f (S fa a) = S foo (f a) where
    foo = (fmap f fa) -- we must do this to keep it of the type S (n b) b

instance (Foldable n) => Foldable (S n) where
  foldMap f (S fa a) = foo <> f a where
    foo = foldMap f fa

instance (Traversable n)
  => Traversable (S n) where
  traverse f (S fa a) = s where
    x = traverse f fa
    y = f a
    s = S <$> x <*> y

mainS = -- why you not work?
  let trigger :: (S [] (Int, Int, [Int]))
      trigger = undefined
  in quickBatch (traversable trigger)
But the output:
traversable:
  fmap:    *** Failed! Falsifiable (after 12 tests and 2 shrinks):
<function>
S [-11,8,-7,-9,-5,3,1,11,2,-10,6] (-8)
LHS
1
  foldMap: +++ OK, passed 500 tests. 

borkdude 2018-07-25T19:51:06.000182Z

Some of the code was already given in the book, but not the Foldable and Traversable instances

2018-07-25T19:53:23.000096Z

just include DeriveFoldable and DeriveTraversable? 😛

borkdude 2018-07-25T19:54:01.000388Z

lol

2018-07-25T19:54:07.000305Z

seriously, not sure exactly what it’s testing so not sure I can help, but let me stare at it a bit

borkdude 2018-07-25T19:54:30.000065Z

I’m afk for 15 minutes

2018-07-25T19:54:33.000449Z

and maybe someone else who is better at Haskell will show up too

2018-07-25T20:03:59.000059Z

@borkdude so is S [-11,8,-7,-9,-5,3,1,11,2,-10,6] (-8) an instance of S n a, where a is Int and n is [] (a list)?

2018-07-25T20:07:26.000187Z

if I’m reading the types correctly, it seems like the foldMap instance is treating the semigroup for n a and a as the same thing

2018-07-25T20:07:37.000333Z

but if it’s type-checking that suggests I’m confused

borkdude 2018-07-25T20:09:12.000118Z

@ddellacosta that’s correct, n is [] and a is Int

borkdude 2018-07-25T20:10:38.000062Z

@ddellacosta hmm, it does type-check, but let me check this

borkdude 2018-07-25T20:11:01.000474Z

it also law-checks

2018-07-25T20:25:16.000400Z

no I’m sorry, I was confused

2018-07-25T20:25:41.000285Z

so yeah your Foldable seems pretty alright

borkdude 2018-07-25T20:28:45.000359Z

yeah, foo is of type m and so is f a

2018-07-25T20:28:53.000431Z

so what about the traverse then…are you sure you want an S n a return value? like if you have a (S n a) and n is Applicative, maybe that needs to be n (S n b) (where b is the output of your a -> f b)? nevermind, was misreading

2018-07-25T20:29:08.000152Z

but again, if it’s type-checking I may be confused

2018-07-25T20:29:23.000044Z

I’m just comparing your code to the type sig for traverse

2018-07-25T20:30:05.000006Z

…and hoping my questions maybe trigger you realizing something, even if I’m offbase

borkdude 2018-07-25T20:30:22.000317Z

the type here is (a -> f b) -> S n a -> f (S n b)

borkdude 2018-07-25T20:31:15.000099Z

so for example:

-- example = S (Just "http://...") "http://..."
-- get :: String -> IO Resp
-- fmap get example :: S (Just (IO resp)) (IO resp)
-- but we want: IO (S (Just resp) resp)

borkdude 2018-07-25T20:32:21.000275Z

this is very confusing

2018-07-25T20:32:24.000016Z

(thinking/reading)

2018-07-25T20:32:29.000510Z

yeah this is a tough one, lots of moving parts

2018-07-25T20:36:19.000457Z

shoot @borkdude I have to go, I’m sorry, if I can get back on and help more I will--you may have more luck posting this in #haskell on IRC though, I bet with the level of folks there someone will immediately point out the issue

borkdude 2018-07-25T20:37:36.000003Z

Example:

type Resp = String
get ::  String -> IO Resp
get s = pure "<html></html>"
example = S (Just "http://") "http://"
test1 :: S Maybe (IO Resp)
test1 = fmap get example
test2 :: IO (S Maybe Resp) 
test2 = traverse get example -- S (Just "<html></html>") "<html></html>"

borkdude 2018-07-25T20:37:43.000338Z

Thanks!

2018-07-25T20:42:20.000134Z

wait so with that example, that’s showing you how it does work now? (except the return value of the last one is in IO I guess, assuming you dumped that out in ghci)

2018-07-25T20:43:50.000077Z

yeah it does, just tried it, okay

2018-07-25T20:45:46.000029Z

damn I can’t see what’s wrong with it, for example just tried this too:

λ> traverse (\n -> [n+1]) (S [1,2,3] 1)
[S [2,3,4] 2]
λ>

2018-07-25T20:46:05.000156Z

okay actually going away now

borkdude 2018-07-25T20:54:26.000315Z

thanks. The full code is here in this gist. I’ll start asking others as well: https://gist.github.com/borkdude/3d7eebe5fd2f7ac1fdca73a8cceb608e

borkdude 2018-07-25T20:54:27.000210Z

borkdude 2018-07-25T21:41:03.000168Z

@ddellacosta mystery solved, the EqProp instance from the book was wrong