Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OverloadedLabels: No instance for IsLabel on record data type

Tags:

haskell

record

In the code below,

{-# LANGUAGE OverloadedLabels #-}
module Foo where

data R = R { x :: Int }

g :: Int
g = #x (R { x = 1 })

I expected this to type-check, but instead I get:

foo.hs:7:5: error:
    • No instance for (GHC.OverloadedLabels.IsLabel "x" (R -> Int))
        arising from the overloaded label ‘#x’
        (maybe you haven't applied a function to enough arguments?)
    • In the expression: #x
      In the expression: #x (R {x = 1})
      In an equation for ‘g’: g = #x (R {x = 1})

Given the Overloaded Record Fields proposal, I expected there to be a built-in instance of IsLabel "x" (R -> Int). Is this still the case or does the implementation deviate from the proposal?

like image 420
Rufflewind Avatar asked Mar 15 '20 22:03

Rufflewind


1 Answers

There is no IsLabel instance for OverloadedLabels in (at least current) base (cf. discussion here). You may want to use some libraries which define an orphan instance such as generic-lens. Of cource, you can define it by yourself:

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}

import GHC.Records
import GHC.OverloadedLabels

instance HasField x r a => IsLabel x (r -> a) where
  fromLabel = getField @x

like image 124
Hogeyama Avatar answered Nov 06 '22 01:11

Hogeyama