Question

I am trying to create a Lens from a getter and a setter which I got from another Lens:

import Control.Lens

idL :: Lens s t a b -> Lens s t a b
idL l = lens (\s -> view l s) (\s b -> set l b s)

However, it fails with an obscure (for me) error:

    Expected type: Getting a s a
      Actual type: (a -> Accessor a b) -> s -> Accessor a t
    In the first argument of `view', namely `l'

What am I doing wrong? It’s probably something really basic, but, alas, I don’t yet know enough about what’s really going on (Getting, Accessors) to unravel it by myself.

Était-ce utile?

La solution

The type of view in lens requires the argument Lens to be of type Lens s s a a. It won't work with the general type Lens s t a b. The reason for this is that you'd need to write many type signatures if the type of view was generalized.

But you can just do what view does, without restricting the type:

import Control.Lens
import Control.Applicative -- This imports Const

idL :: Lens s t a b -> Lens s t a b
idL l = lens (\s -> getConst $ l Const s) (\s b -> set l b s)

I used Const instead of the Accessor type, so that code will work with lens HEAD too (which removed the Accessor newtype)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top