'Guards (If-Else) Inside Lambda Function in Haskell

I wanted to write a function that removes minimum value from an array in Haskell. One of the solutions that I developed in Scheme was

(define removemin-cps
  (lambda (lis return)
    (cond
      [(null? lis) (return ('null '()))]
      [(null? (cdr lis)) (return (car lis) '())]
      [else (removemin-cps (cdr lis) (lambda (v1 v2)
                                      (if (< v1 (car lis))
                                          (return v1 (cons (car lis) v2))
                                          (return (car lis) (cons v1 v2)))))])))

(define removemin
  (lambda (lis)
    (removemin-cps lis (lambda (v1 v2)  v2))))

I wanted to try something similar in Haskell and ran into the problem that I cannot use either guards or if-else statements inside lambda. Here is what I have:

removemin_cps [] return = return null []
removemin_cps [h] return = return h []
removemin_cps (h:t) return = removemin_cps t (\v1 v2 ->
                                                | v1 < h       -> return v1 (h:v2)
                                                | otherwise    -> return h (v1:v2))

Can I use guards or if-else statements inside lambda or should I come up with another solution to the problem?

Thanks!



Solution 1:[1]

So, instead of null I used Nothing and it fixed the problem with the code not compiling but now I'm just very confused about the types. How do I change the type structure so this works? I'm very new to Haskell and its been a nightmare so far...

removemin_cps :: (Ord a) => [Maybe a] -> (Maybe a -> [Maybe a] -> p) -> p
removemin_cps [] return = return Nothing []
removemin_cps [h] return = return h []
removemin_cps (h:t) return = removemin_cps t (\v1 v2 -> 
                                                if v1 < h
                                                    then        
                                                         return v1 (h:v2)
                                                    else
                                                         return h (v1:v2))

This is what I get when I call the function:

*Main> removemin_cps [3 2 0 1] (\v1 v2 -> v2)

<interactive>:2:1: error:
    • Non type-variable argument
        in the constraint: Num (t1 -> t2 -> t3 -> Maybe a)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall a t1 t2 t3.
              (Ord a, Num t1, Num t2, Num t3, Num (t1 -> t2 -> t3 -> Maybe a)) =>
              [Maybe a]
*Main> 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1