1
votes
orderedq f [] = True
orderedq f (x:[]) = True
orderedq f (x:y:zs) = and [(f x y), (orderedq f zs)]

num_orderedq xs = orderedq <= xs

ghci says, when trying to load using :l [file name] says:

[1 of 1] Compiling Main             ( route-combinations.hs, interpreted )

route-combinations.hs:9:1: error:
    * Non type-variable argument
        in the constraint: Ord ((t -> t -> Bool) -> [t] -> Bool)
      (Use FlexibleContexts to permit this)
    * When checking the inferred type
        num_orderedq :: forall t.
                        Ord ((t -> t -> Bool) -> [t] -> Bool) =>
                        ((t -> t -> Bool) -> [t] -> Bool) -> Bool
  |
9 | num_orderedq xs = orderedq <= xs
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.

Is my typing wrong?

What is the correct type signature for the code? It doesn't accept this:

orderedq :: (a -> a -> Bool) -> [a] -> Bool
orderedq f [] = True
orderedq f (x:[]) = True
orderedq f (x:y:zs) = and [(f x y), (orderedq f zs)]

num_orderedq :: [a] -> Bool
num_orderedq xs = orderedq <= xs
2
orderedq is a function, so this can not be "smaller" than xs.Willem Van Onsem
So the problem is not with the signature. Haskell can automatically derive most signatures, the problem is with the fact that you compare a function with a list of elements.Willem Van Onsem
What do you mean by smaller? Are you refering to the line containing num_orderedq xs = orderedq <= xs? I am trying to pass <= and xs as arguments. If the problem is that <= is being assumed to be an infix function, how can I know that this is the case with functions in the future, and pass that function to another function?SultanLegend

2 Answers

4
votes

You said that your intention with the line

num_orderedq xs = orderedq <= xs

was to pass two arguments to orderedq: the <= function and xs. Syntactically, though, you need to enclose an operator in parentheses when you’re using it in this context:

num_orderedq xs = orderedq (<=) xs

Operators and functions are semantically the same thing in Haskell; the only difference is their syntax. See this question and its answers for more on the differences between operators and other functions.

3
votes

If you write orderedq <= xs, then this is interpreted as (<=) orderedq xs, with (<=) :: Ord a => a -> a -> Bool a comparison to check if the left operand is less than or equal to the right operand.

It thus aims to compare orderedq with xs. But this is not possible, since orderedq is a function, and regardless what xs is, normally functions are not ordered (no instance of Ord).

If you want to pass the (<=) function, you can write:

num_orderedq :: Ord a => [a] -> Bool
num_orderedq = orderedq (<=)

Note that your orderedq can be rewritten to:

orderedq :: (a -> a -> Bool) -> [a] -> Bool
orderedq f [] = True
orderedq f xa@(_:xs) = and (zipWith f xa xs)