Reputation: 1535
Such as:
extract (f x) = x
What I want to do is to extract the parameter from a function or a type constructor, such as
extract succ 4 = 4
extract Just 4 = 4
ps. extract (f x) = f doesn't work either.
Upvotes: 1
Views: 170
Reputation: 116139
The "extracting the argument from a function" would require to invert said function, which is possible only if the function is injective. More to the point, assume
square x = x*x
and
root (square x) = x -- assume it works, somehow
We should have
root (square 2) = 2
root (square (-2)) = -2
root 4 = ???
The last 4
is both the square of 2
and -2
, and there's no single result we can associate to it. The square
function is not injective, so its inverse is not even a function.
Worse, since 4
is equal to both the squares above, referential transparency mandates that the two lines above return the same result. This can not be the case, though.
Upvotes: 4
Reputation: 3946
You definitely can pattern match against the structure of your data with a data constructor, like your example, Just
. What you need is to wrap it in parentheses, (Just 4)
, otherwise your extract
function looks like it would be taking a data constructor, and not a constructed value.
In your case, you would want:
extract (Just x) = x
That's, in fact, part of the fromJust
function.
The other answer explains why you can't match against function application. To that, I'll add that it would be kind of like a magic way to get an inverse function. If there was an extract (f x) = x
, it would be like magically having a g
such that g . f = id
. In your case, you defined a function succ
which I presume would be
succ x = x+1
Now, if extract (succ x) = x
was possible, because of equational reasoning, extract
would of type Integer -> Integer
and you would magically have constructed the inverse of succ
, x-1
.
What is possible though, like I showed above, is matching against the structure of data.
You can define, instead of a function succ
working on Integer
s, a new datatype:
data Nat = Zero | Succ Nat
And then easily have an extract function:
extra Zero = Zero
extract (Succ x) = x
Just remember that you can, and are in fact encouraged to, to pattern match against things like (Just x)
.
Upvotes: 1
Reputation: 48580
One of the key concepts in functional programming, and especially pure functional programming, is equational reasoning. The =
in Haskell is actual equality (leaving aside order of pattern matching and such). So when we write
f 3 = 12
that means f 3
and 12
are actually the same thing—completely indistinguishable. Since extract 12
doesn't make any sense, neither does extract (f 3)
.
To come at it from another direction, at run-time, there is no way to tell that a certain value was formed by applying a certain function to a certain other value. Making such information available would generally be very expensive, and would not often be useful.
Upvotes: 6