Ad
  • Custom User Avatar

    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.

  • Custom User Avatar

    The initial solution exports everything, so that isn't a problem, is it?

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    Thanks for the feedback!
    I added these clarifications to the initial code for .= and toString.

  • Custom User Avatar

    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
    
  • Custom User Avatar

    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.

    # python 3
    >>> list(range(10))
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(range(5, 10))
    [5, 6, 7, 8, 9]
    >>> list(range(5, 10, 2))
    [5, 7, 9]
    >>> list(range(10, 5))
    []
    
  • Custom User Avatar

    This is a cool kata! I found a two points of frustrations, though.

    1. There are no tests for the individual operators. Finding out what exactly went wrong on these big programs is annoying.
    2. Not all operators are actually tested/needed. You can get a shorter solution if you simply ignore the untested operators.
  • Custom User Avatar

    Looks like your code is mutating the list, which is not allowed by the kata and the reason for the weird side effect you are seeing.
    Trying running this on your code, which will give the wrong answer, just like in the test you posted:

    const l0 = List.iterate(a => a + 1, 0)
    l0.take(10).toList()
    console.log(l0.take(10).toList()) // prints [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
    
  • Custom User Avatar

    I tried using the constructor and ran into this, too.

    You don't need the constructor, though.
    The kata is solvable with just the provided imports, so I don't think this is an issue.

  • Custom User Avatar

    Ah yes you are right. I changed the imports to back to being explicit.

  • Custom User Avatar

    Good point. I made sure that each of these operations works with at least two different types (like Int and Float). That should be enough right?

    To make my life easier when testing I also added the (.=) function to implement. With that we also can have a nice isEven program, which I added aswell.

    Last change is to the export/import list. Now everything is exported/imported by default, so that I don't have to touch these anymore if I decide to change an export again.

    (These changes invalidated your solution)

  • Custom User Avatar

    I used data so that I can define the left-hand side of the type while leaving the right-hand side out.
    newtype won't let me do that, but for the solution either newtype or data is fine.

  • Custom User Avatar

    The module Skeleton was a mistake on my part. I replaced it with the correct module Imperative.

    I removed the unexported functions from the initial solution, I didn't have a good reason to include them.
    I also added the missing type definition for def.

    Lasty, probably the biggest change, I removed the TODO types. while/if/else are now fully typed.
    That means that the typeclass I used also appears in the initial solution.

    The Imperative type is still hidden, because I think it's interesting to figure out how to implement it.

    Does it look better now?
    I am a bit worried that the variable/value typeclass thing is a bit too much at once.

    Oh and with the removal of the TODO types the initial solution now compiles, which I think is great.

  • Custom User Avatar

    You'd have to lift the built-in comparator and the value into the monad, of course, but that can be done polymorphically, so painlessly.

    I can image this being done by redefining the operators (for example (<) = someLiftFunction P.(<)), which I would like to avoid.
    How can it be done more painlessly?

    Maybe my approach is already more complicated than it needs to be. For example while someVar (< 0) is a bit simpler because it only accepts a Var on the left side.

    The meat of the kata should be defining mutable variabes and the if/else control flow, while keeping some kind of clean python-like syntax.

    Let me know if you feel like there is anything else in the kata that makes it more convoluted than necessary.

  • Custom User Avatar

    Thanks for the feedback!

    I use the more complicated signature to make it possible to compare both variables and values using built-in functions like (<).
    With Bool we wouldn't be able to compare the mutable variables we create. For example:

    prog = def do
      a <- var 1 -- a has type `Var st Int`
      while a (<) 3 do -- here we compare `Var st Int` with `Int`
        ...
    

    Does this make sense? If so I would add a hint for that.

    It looks like this kata tried a different approach in the past, where Vars were instances of Num, but ended up with a version that's similar to what I am using here.

  • Loading more items...