I'm trying to follow this tutorial: http://blog.jakubarnold.cz/2014/08/06/lens-tutorial-stab-traversal-part-2.html
I'm using the following code that I load into ghci:
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
import Control.Applicative
import Data.Functor.Identity
import Data.Traversable
-- Define Lens type.
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a
-- Lens view function. Omitting other functions for brevity.
view :: Lens s t a b -> s -> a
view ln x = getConst $ ln Const x
-- Tutorial sample data types
data User = User String [Post] deriving Show
data Post = Post String deriving Show
-- Tutorial sample data
john = User "John" $ map (Post) ["abc","def","xyz"]
albert = User "Albert" $ map (Post) ["ghi","jkl","mno"]
users = [john, albert]
-- A lens
posts :: Lens' User [Post]
posts fn (User n ps) = fmap (\newPosts -> User n newPosts) $ fn ps
From there, simple stuff like this works:
view posts john
However, when I try to do the next step it does not work:
view (traverse.posts) users
I get:
Could not deduce (Applicative f) arising from a use of ‘traverse’
from the context (Functor f)
bound by a type expected by the context:
Functor f => ([Post] -> f [Post]) -> [User] -> f [User]
at <interactive>:58:1-27
Possible fix:
add (Applicative f) to the context of
a type expected by the context:
Functor f => ([Post] -> f [Post]) -> [User] -> f [User]
In the first argument of ‘(.)’, namely ‘traverse’
In the first argument of ‘view’, namely ‘(traverse . posts)’
In the expression: view (traverse . posts) users
I see that Lens has a type constraint of Functor and traverse has a more constrained type constraint on f as an Applicative. Why exactly isn't this working and why did the blog tutorial suggest that it works?
Lens,Lens', andviewand instead import them fromControl.Lens, it works, though that still leaves the question of why yours aren’t working. - icktoofay