haskell - Ambiguous type variable when updating two record fields at a time (but not when updating one!) -
the following code fails "ambiguous type variable" error (bottom). however, alternate definition updates record twice works fine: why this? further, "broken" definition below similar 1 in trifecta source. i'm compiling ghc 7.10.3 against trifecta 1.5.2 , parsers 0.12.3.
module main import text.trifecta import text.parser.token.style t -- definition causes type error identstyle :: tokenparsing m => identifierstyle m identstyle = t.emptyidents { _stylestart = letter , _styleletter = letter }
here working (alternative) definition
identstyle :: tokenparsing m => identifierstyle m identstyle = t.emptyidents { _stylestart = letter } { _styleletter = letter }
the error generated first definition is:
main.hs:10:3: not deduce (tokenparsing t0) arising use of ‘emptyidents’ context (tokenparsing m) bound type signature identstyle :: tokenparsing m => identifierstyle m @ main.hs:8:15-49 type variable ‘t0’ ambiguous note: there several potential instances: instance attoparsec-0.13.0.1:data.attoparsec.internal.types.chunk t => tokenparsing (attoparsec-0.13.0.1:data.attoparsec.internal.types.parser t) -- defined in ‘text.parser.token’ instance tokenparsing text.parsercombinators.readp.readp -- defined in ‘text.parser.token’ instance tokenparsing m => tokenparsing (unhighlighted m) -- defined in ‘text.parser.token’ ...plus 11 others in expression: emptyidents in expression: emptyidents {_stylestart = letter, _styleletter = letter} in equation ‘identstyle’: identstyle = emptyidents {_stylestart = letter, _styleletter = letter} failed, modules loaded: none.
hah, kind of funny problem.
the issue here emptyidents
class-polymorphic. when use it, part of type inference algorithm has define instance use.
when modify 1 field @ time, type of record isn't permitted change; is, type of \record -> record { _stylestart = undefined }
identifierstyle m -> identifierstyle m
. demanding final type of
emptyidents { _stylestart = letter } { _styleletter = letter }
is identifierstyle m
, can infer first emptyidents
identifierstyle m
with same type m
argument.
on other hand, how record update works in haskell, when update both fields @ once (which happens fields types mention type argument m
), update becomes polymorphic. is, type of \record -> record { _stylestart = undefined, _styleletter = undefined }
identifierstyle m' -> identifierstyle m
-- note prime!
so in case both updates @ once like
emptyidents { _stylestart = letter, _styleletter = letter }
then fixing final type of update @ identifierstyle m
not determine type of emptyidents
.
there's half dozen ways fix this, basic idea should fix instance use while building emptyidents
.
Comments
Post a Comment