2

I'm just trying to do the bare minimum to translate the following Haskell to Idris (I'm not looking for efficiency or proofs of correctness):

quicksort  []           =  []
quicksort (x:xs)        =  quicksort [y | y <- xs, y<x ]
                        ++ [x]
                        ++ quicksort [y | y <- xs, y>=x]

Here's the Idris code I have, which is essentially unchanged from the Haskell except for needing to tell Idris that we are dealing with Ordered types:

quicksort: List (Ord b) -> List (Ord b)
quicksort  []           =  []
quicksort (x::xs)       =  quicksort [y | y <- xs, y<x ]
                        ++ [x]
                        ++ quicksort [y | y <- xs, y>=x]

However, I'm apparently doing this wrong. I see there is an answer in the question at Quicksort in Idris , but the form is a bit different - I'd like to understand what is wrong with the current approach. My above code gives the error:

40 | quicksort (x::xs)       =  quicksort [y | y <- xs, y<x ]
   |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
When checking right hand side of quicksort with expected type
        List b

When checking an application of function Prelude.Applicative.guard:
        Can't find implementation for Ord (Ord b)
bbarker
  • 11,636
  • 9
  • 38
  • 62

2 Answers2

1

The problem is that Prelude.Applicative.guard (function which is used for guards in list comprehensions) can't find implementation for Ord typeclass.

That tells us, that we haven't added (or added incorrectly) typeclass constraint. If we change your code to this one, it should work:

quicksort: Ord b => List b -> List  b
quicksort  []           =  []
quicksort (x::xs)       =  quicksort [y | y <- xs, y < x ]
                        ++ [x]
                        ++ quicksort [y | y <- xs, y >= x]
Igor Drozdov
  • 14,690
  • 5
  • 37
  • 53
  • OK, that makes sense - I hadn't seen type classes in either language yet. What seems a bit surprising to me is that it is `guard` that requires an instance of the type class, and not the comparison operators; I think of guard as just saying "such that", and what follows "such that" could be something involving equality rather than inequalities. – bbarker May 08 '18 at 12:53
  • what is `Alternative` in Idris - is it also builtin? my knowledge of Idris isn't good enough to know if my grepping was complete in trying to find its definition, but as guard uses it, I guess maybe the Ord requirement comes from there? – bbarker May 09 '18 at 02:35
  • do you have any ideas on why `guard` requires `Ord`, or should I ask this as another question? – bbarker May 09 '18 at 18:13
1

To clarify: List (Ord b) is a list of implementations for Ord b, while Ord b => List b is a list of b where b has the interface constraint of Ord b. Compare:

[ord1] Ord Nat where
   compare Z (S n)     = GT
   compare (S n) Z     = LT
   compare Z Z         = EQ
   compare (S x) (S y) = compare @{ord1} x y

imps : List (Ord b) -> List (Ord b)
imps xs = xs

ords : Ord b => List b -> List b
ords xs = xs

With imps [ord1] : List (Ord Nat) and ords [1] : List Nat.

xash
  • 3,702
  • 10
  • 22