Thanks for the suggestion. I have added NoPolyKinds to the initial solution.
I didn't need it in my solution, but haven't investigated where exactly the issue comes from, yet.
Seems like the original solution was automaticly ported to a new GHC version, and that broke it. The code compiles fine with NoPolyKinds language extension set, so i propose enabling it
My solution passes sample tests, but fails to compile on submission
test/ImperativeSpec.hs:216:1: error:
• Uninferrable type variable k10 in
the type synonym right-hand side:
forall v st (s :: k10).
HasValue st v b =>
Var st a -> v -> Imperative @{k10} @{k10} st s s ()
• In the type declaration for ‘Op’
|
216 | type Op a b = forall v st s. HasValue st v b => Var st a -> v -> Imperative st s s ()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Hmmm, you're right. Apparently, I didn't check the initial solution before posting this. I've encountered that error because I added an export list (probably copied it from sample tests' imports). Export lists play nicely with IDEs. For instance, they allow me to "rename symbol" in VSCode. I suggest adding one
return an Imperative … s s …, which allows
putting these statements between if', elif' and else':
-- Note how far apart are if' and else'.example::Stringexample=defdoresult<-var"value doesn't matter"if'0 (==) 0doresult.="body doesn't matter"varBetween<-var"value doesn't matter"while0 (/=) 0doresult.="body doesn't matter"else'doresult.="body doesn't matter"returnresult
I'd prefer if this was illegal
and the types of non-branching statements
were restricted to Imperative … s NothingYet …,
given the kata's focus on type correctness.
But sure, this can be seen as an intentional language feature.
And things will probably stay the same
to avoid extra work, breaking existing solutions, etc.
You may even add tests that cover this feature.
I think that error message is a result of UndecidableInstances masking the real problem. Without that option, GHC throws an error, that it can not see, that the functional dependency t → r is satisfied in the second instance:
• Illegal instance declaration for ‘Variadic a r (a' -> t)’
The coverage condition fails in class ‘Variadic’
for functional dependency: ‘t -> r’
Reason: lhs type ‘a' -> t’ does not determine rhs type ‘r’
Un-determined variable: r
Using UndecidableInstances might help
• In the instance declaration for ‘Variadic a r (a' -> t)’
|
13 | instance (a ~ a', Variadic a r t) => Variadic a r (a' -> t) where
|
Removing the functional dependency resolves that, but then GHC complains about an ambiguous type in polyList.
I have no idea how to resolve that. I have been banging my head against the wall for a whole day trying to get a similar solution working, before settling for a less elegant solution.
The meaning of the (.=) operation should be clarified (in the initial code comments). It took me some time to realized that it is an assignment operation.
Also, I suggest to clarify that toString is supposed to work with variables only (otherwise it is necessary to use another GHC extension to type check it).
This solution breaks on GHC 9.0, which is unfortunate because I really like it.
Even after reading the migration guide I have no clue what causes the issue in this case. Does someone know how to fix this solution on GHC 9.0+?
• Couldn't match type ‘Int -> Int’ with ‘Int’
arising from a functional dependency between:
constraint ‘Variadic Int Int (Int -> Int)’
arising from a use of ‘polyAdd’
instance ‘Variadic a r r’
at oneFunctionManyArguments.hs:14:10-23
• In the expression: polyAdd 1
In an equation for ‘a’: a = polyAdd 1
It looks very similar to the range function from python to me (excluding the step = 0 case).
So I don't think it is that strange to want such behavior.
Thanks for the suggestion. I have added
NoPolyKinds
to the initial solution.I didn't need it in my solution, but haven't investigated where exactly the issue comes from, yet.
Seems like the original solution was automaticly ported to a new GHC version, and that broke it. The code compiles fine with
NoPolyKinds
language extension set, so i propose enabling itMy solution passes sample tests, but fails to compile on submission
Idk, it looks like an internal problem
Hmmm, you're right. Apparently, I didn't check the initial solution before posting this. I've encountered that error because I added an export list (probably copied it from sample tests' imports). Export lists play nicely with IDEs. For instance, they allow me to "rename symbol" in VSCode. I suggest adding one
The initial solution exports everything, so that isn't a problem, is it?
In case anyone is interested in creating another follow-up imperative kata, it would be cool to require correct early returns:
Just an observation: default signatures like
return an
Imperative … s s …
, which allowsputting these statements between
if'
,elif'
andelse'
:I'd prefer if this was illegal
and the types of non-branching statements
were restricted to
Imperative … s NothingYet …
,given the kata's focus on type correctness.
But sure, this can be seen as an intentional language feature.
And things will probably stay the same
to avoid extra work, breaking existing solutions, etc.
You may even add tests that cover this feature.
Submission tests expect
HasValue
,Imperative
andVar
to be exported. Consider adding these to the export list in the initial solution templateI think that error message is a result of
UndecidableInstances
masking the real problem. Without that option, GHC throws an error, that it can not see, that the functional dependencyt → r
is satisfied in the second instance:Removing the functional dependency resolves that, but then GHC complains about an ambiguous type in
polyList
.I have no idea how to resolve that. I have been banging my head against the wall for a whole day trying to get a similar solution working, before settling for a less elegant solution.
This comment is hidden because it contains spoiler information about the solution
Thanks for the feedback!
I added these clarifications to the initial code for
.=
andtoString
.The meaning of the
(.=)
operation should be clarified (in the initial code comments). It took me some time to realized that it is an assignment operation.Also, I suggest to clarify that
toString
is supposed to work with variables only (otherwise it is necessary to use another GHC extension to type check it).This solution breaks on GHC 9.0, which is unfortunate because I really like it.
Even after reading the migration guide I have no clue what causes the issue in this case. Does someone know how to fix this solution on GHC 9.0+?
It looks very similar to the
range
function from python to me (excluding the step = 0 case).So I don't think it is that strange to want such behavior.
This is a cool kata! I found a two points of frustrations, though.
Loading more items...