given this piece of code:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FunctionalDependencies #-}
module Foo where
import Control.Lens ((^.), makeFieldsNoPrefix)
import Prelude hiding (id)
data Bar
= Bar1 { _id :: Int
, _name :: String
}
| Bar2 { _name :: String }
$(makeFieldsNoPrefix ''Bar)
data Foo = Foo { _id :: Int
, _name :: String
}
$(makeFieldsNoPrefix ''Foo)
a = (undefined :: Foo) ^. name -- compiles fine
b = (undefined :: Foo) ^. id -- doesnt compile
{-
• No instance for (Monoid Int) arising from a use of ‘id’
• In the second argument of ‘(^.)’, namely ‘id’
In the expression: (undefined :: Foo) ^. id
In an equation for ‘b’: b = (undefined :: Foo) ^. id
-}
As far as I can understand, it seems id
needs an instance of Monoid because of Bar that could fail when the instance is of type Bar2
(which doesnt have an id
field).
But since I'm working on a Foo (which always has an id
field) it should work, doesnt it ?
I know I could solve this with prefixing the field with the class name like:
data Foo = Foo { _fooId :: Int, _fooName :: String }
but if there is a nice solution without cluttering my fields name then I'm all for it :-)