Skip to content

Commit

Permalink
Add instance AsType a a (#149)
Browse files Browse the repository at this point in the history
* Add instance AsType a a

Resolves #146

* Update ChangeLog.mds

* docs: expand definition of {As,Has}Type; document reflexive instances

* docs: make generic-optics/ChangeLog.md mirror generic-lens/ChangeLog.md

* format: remove trailing newlines
  • Loading branch information
lrworth committed Apr 4, 2024
1 parent 09bd6c7 commit cbe168c
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 6 deletions.
4 changes: 4 additions & 0 deletions generic-lens/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
- Add `OverloadedLabels` support for positional lenses, e.g. `#3` as an
abbreviation for `position @3`, starting with GHC 9.6.

### Breaking API changes:
- `AsType` now includes a reflexive case for consistency with `HasType`: every
type can be treated 'as' itself.

## generic-lens-2.2.2.0 (2023-04-15)
- Support unprefixed constructor prisms on GHC 9.6 (#152)

Expand Down
3 changes: 2 additions & 1 deletion generic-lens/generic-lens.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ test-suite inspection-tests
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
other-modules: Util Test24 Test88 Test25 Test40 Test62 Test63 CustomChildren
other-modules: Util Test24 Test88 Test25 Test40 Test62 Test63 Test146 CustomChildren

build-depends: base
, generic-lens
, lens
, mtl
, profunctors
, inspection-testing >= 0.2
, HUnit
Expand Down
4 changes: 3 additions & 1 deletion generic-lens/src/Data/Generics/Product/Typed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ import "generic-lens-core" Data.Generics.Internal.Void
-- human = Human "Tunyasz" 50 "London" False
-- :}

-- |Records that have a field with a unique type.
-- |Types that contain another type, either by being a record with a field
-- with that type, or by actually being that type.
class HasType a s where
-- |A lens that focuses on a field with a unique type in its parent type.
-- Compatible with the lens package's 'Control.Lens.Lens' type.
Expand Down Expand Up @@ -102,6 +103,7 @@ instance Core.Context a s => HasType a s where
typed = VL.ravel Core.derived
{-# INLINE typed #-}

-- |Every type 'has' itself.
instance {-# OVERLAPPING #-} HasType a a where
getTyped = id
{-# INLINE getTyped #-}
Expand Down
8 changes: 7 additions & 1 deletion generic-lens/src/Data/Generics/Sum/Typed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ import "generic-lens-core" Data.Generics.Internal.Void
-- :}


-- |Sums that have a constructor with a field of the given type.
-- |Types that can represent another type, either by being a sum with a
-- constructor containing that type, or by actually being that type.
class AsType a s where
-- |A prism that projects a constructor uniquely identifiable by the type of
-- its field. Compatible with the lens package's 'Control.Lens.Prism' type.
Expand Down Expand Up @@ -97,6 +98,11 @@ class AsType a s where

{-# MINIMAL (injectTyped, projectTyped) | _Typed #-}

-- |Every type can be treated 'as' itself.
instance {-# OVERLAPPING #-} AsType a a where
injectTyped = id
projectTyped = Just

instance Core.Context a s => AsType a s where
_Typed eta = prism2prismvl Core.derived eta
{-# INLINE _Typed #-}
Expand Down
1 change: 1 addition & 0 deletions generic-lens/test/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import Data.Generics.Labels ()
import Test24 ()
import Test25 ()
import Test88 ()
import Test146 ()

import CustomChildren (customTypesTest)

Expand Down
17 changes: 17 additions & 0 deletions generic-lens/test/Test146.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}

module Test146 where

import Control.Monad.Except
import Data.Generics.Sum
import GHC.Generics

data Error = Error
deriving (Generic)

poly :: (AsType Error e, MonadError e m) => m ()
poly = undefined

mono :: ExceptT Error IO ()
mono = poly
6 changes: 6 additions & 0 deletions generic-optics/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Unreleased

### Breaking API changes:
- `AsType` now includes a reflexive case for consistency with `HasType`: every
type can be treated 'as' itself.

## generic-optics-2.2.1.0 (2022-01-22)
- GHC 9.2 compatibility

Expand Down
3 changes: 2 additions & 1 deletion generic-optics/generic-optics.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ test-suite generic-optics-inspection-tests
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
other-modules: Util Test24 Test88 Test25 Test40 Test62 Test63 CustomChildren
other-modules: Util Test24 Test88 Test25 Test40 Test62 Test63 Test146 CustomChildren

build-depends: base
, generic-optics
, mtl
, optics-core
, inspection-testing >= 0.2
, HUnit
Expand Down
4 changes: 3 additions & 1 deletion generic-optics/src/Data/Generics/Product/Typed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ import "generic-lens-core" Data.Generics.Internal.Void
-- human = Human "Tunyasz" 50 "London" False
-- :}

-- |Records that have a field with a unique type.
-- |Types that contain another type, either by being a record with a field
-- with that type, or by actually being that type.
class HasType a s where
-- |A lens that focuses on a field with a unique type in its parent type.
--
Expand Down Expand Up @@ -103,6 +104,7 @@ instance Core.Context a s => HasType a s where
typed = normaliseLens (Optic Core.derived)
{-# INLINE typed #-}

-- |Every type 'has' itself.
instance {-# OVERLAPPING #-} HasType a a where
getTyped = id
{-# INLINE getTyped #-}
Expand Down
8 changes: 7 additions & 1 deletion generic-optics/src/Data/Generics/Sum/Typed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ import "generic-lens-core" Data.Generics.Internal.Void
-- :}


-- |Sums that have a constructor with a field of the given type.
-- |Types that can represent another type, either by being a sum with a
-- constructor containing that type, or by actually being that type.
class AsType a s where
-- |A prism that projects a constructor uniquely identifiable by the type of
-- its field.
Expand Down Expand Up @@ -97,6 +98,11 @@ class AsType a s where

{-# MINIMAL (injectTyped, projectTyped) | _Typed #-}

-- |Every type can be treated 'as' itself.
instance {-# OVERLAPPING #-} AsType a a where
injectTyped = id
projectTyped = Just

instance Core.Context a s => AsType a s where
_Typed = normalisePrism (Optic Core.derived)
{-# INLINE _Typed #-}
Expand Down
1 change: 1 addition & 0 deletions generic-optics/test/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Optics.Core
-- This is sufficient at we only want to test that they typecheck
import Test24 ()
import Test25 ()
import Test146 ()

-- import CustomChildren (customTypesTest)

Expand Down
17 changes: 17 additions & 0 deletions generic-optics/test/Test146.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}

module Test146 where

import Control.Monad.Except
import Data.Generics.Sum
import GHC.Generics

data Error = Error
deriving (Generic)

poly :: (AsType Error e, MonadError e m) => m ()
poly = undefined

mono :: ExceptT Error IO ()
mono = poly

0 comments on commit cbe168c

Please sign in to comment.