I made a function that identifies if a certain object has repetition as following: (PS: test is passing)
(* ListOfPattern -> Pattern -> String List -> List.exists (function) -> bool*)
val check_pat =
let
fun patternToVars p =
case p of
Variable x => [x]
| TupleP lop => List.foldl (fn (p, acc) => (patternToVars p) @ acc) [] lop
| _ => []
fun isDuplicated lov =
case lov of
[] => false
| lov::lov' => List.exists (fn prevString => prevString = lov) lov' orelse isDuplicated lov'
in
not o isDuplicated o patternToVars
(* Cannot understand why `not o` works but `not` does not, duplicate returns bool in all
cases and there is no need for piping *)
end
But if I remove o
from not o isDuplicated o patternToVars
and make it not isDuplicated o patternToVars
it returns the following error:
Error: operator and operand don't agree [tycon mismatch]
operator domain: bool
operand: ''Z list -> bool
in expression:
not isDuplicated
And the question is "why isDuplicated
returning a list?"
The message does not say that isDuplicated
returns a list, it says that isDuplicated
is a function with the type ''Z list -> bool
, and that you're trying to apply not
to it when not
requires a bool
argument.
not o
is not a meaningful "unit"; o
is a binary operator, and f o g
is equivalent to fn x => f (g x)
.
Because function application has higher precedence than o
,
not isDuplicated o patternToVars
is equivalent to
(not isDuplicated) o patternToVars
That is, you're trying to negate the function isDuplicated
, not its result.
Perhaps your particular issue becomes more obvious if you add the argument and nest explicit function applications; the first is equivalent to
fn p => not (isDuplicated (patternVars p))
while the second is equivalent to
fn p => (not isDuplicated) (patternVars p)
which you can see is very different.
Another attempt to clarify:
Perhaps it becomes clearer if we define composition as a function instead of as an infix operator:
fun compose (f, g) = fn x => f (g x)
or even
fun compose (f, g) = f o g
Then,
not o isDuplicated o patternToVars
is the same as
compose (not, compose (isDuplicated, patternToVars))
while
not isDuplicated o patternToVars
is the same as
compose (not isDuplicated, patternToVars)