Description
optics-core
supports using overloaded labels as field lenses (and constructor prisms) for types with a Generic
instance since 0.4.
Consider the following module (full project for ease of reproducibility is here).
{-# LANGUAGE DeriveGeneric, OverloadedLabels #-}
module Main where
import Optics.Core
import GHC.Generics (Generic)
data User p = User { name :: String, age :: Int }
deriving (Show, Generic)
getName_gotoWorks :: User p -> String
getName_gotoWorks u = name u
getName_gotoDoesntWork :: User p -> String
getName_gotoDoesntWork u = u ^. #name
setFields_ambiguousMiddleType :: User p -> User p
setFields_ambiguousMiddleType u = u & #name .~ "Tom"
& #age .~ 45
main :: IO ()
main = pure ()
With name
in the definition of getName_gotoWorks
jumping to the definition works fine. However, trying to do the same using #name
within getName_gotoDoesntWork
doesn't.
Would it be possible to add a support for this? On hover the term #name
is a dictionary for IsLabel "name" (Optic' A_Lens NoIx (User p) String)
, so in principle it's possible to go to the field definition as all the information is there.
A somewhat more complicated case is in setFields_ambiguousMiddleType
: hovering over #name
there shows just IsLabel
, presumably due to undetermined phantom type variable (since getting rid of the type variable show the full type) 🤔 Hovering over #age
gives all the dictionary info (IsLabel "age" (Optic A_Lens NoIx (User Any) (User p) Int Int
).
Output of haskell-language-server --probe-tools
:
haskell-language-server version: 1.0.0.0 (GHC: 8.10.4) (PATH: /home/unknown/.cabal/store/ghc-8.10.4/haskell-language-server-1.0.0.0-e-haskell-language-server-789994ec071fd92b667a696b70ccf6882ad277e8ef1bfac3a85c7a034386e70e/bin/haskell-language-server)
Tool versions found on the $PATH
cabal: 3.4.0.0
stack: 2.3.3
ghc: 8.10.4