You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Nov 18, 2023. It is now read-only.
Sometimes one may wish to use different operations for matrix multiplication than the usual ring operations of the Num instance. For instance, one may find the transitive closure of a relation (represented by a boolean matrix) by iterating matrix multiplication with ^(Haskell &&) instead of the algebraic boolean addition. Were a Num instance to be defined with the ^ operation, it would not have a well-behaving negate, so defining such an instance is a poor and dangerous solution. But, due to the absence of parametric matrix multiplication, defining such a broken instance is the only way to obtain the transitive closure using matrix multiplication on Bool.
I propose that we add operations multStdBy and so on, that accept two functions as arguments — one to use as addition, another as multiplication. Note that the ^ operation can be defined in terms of the algebraic operations (as x ^ y = x + y + xy) which can be safely represented by a Num instance for a data type with two members, giving a nice and safe solution for my example.
The text was updated successfully, but these errors were encountered:
I think you can solve this by using newtype. Say you want to use a certain type T with a different implementation of + and *. Then you create a newtype wrapper for T:
newtype U = U T
And now you define a different Num instance for U. You can easily go back and forth between the two types.
@Daniel-Diaz That is how I was working around it, but I decided to remove this Num instance because it is dangerous, as I described in the first post above. So now I am projecting to Integer, doing multiplications there and then retracting the projection with fmap (toEnum . signum). Whichever way I go around it, there are drawbacks:
Unlawful Num: Dangerous — either negate is undefined or exists x y. x + (-x) /= y + (-y).
Projection to Integer: Comes with performance penalty, as Integer addition and multiplication are way more computationally intensive.
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Sometimes one may wish to use different operations for matrix multiplication than the usual ring operations of the
Num
instance. For instance, one may find the transitive closure of a relation (represented by a boolean matrix) by iterating matrix multiplication with^
(Haskell&&
) instead of the algebraic boolean addition. Were aNum
instance to be defined with the^
operation, it would not have a well-behavingnegate
, so defining such an instance is a poor and dangerous solution. But, due to the absence of parametric matrix multiplication, defining such a broken instance is the only way to obtain the transitive closure using matrix multiplication onBool
.I propose that we add operations
multStdBy
and so on, that accept two functions as arguments — one to use as addition, another as multiplication. Note that the^
operation can be defined in terms of the algebraic operations (asx ^ y = x + y + xy
) which can be safely represented by aNum
instance for a data type with two members, giving a nice and safe solution for my example.The text was updated successfully, but these errors were encountered: