The trouble is relatively minimal, at least to get the basics working:
struct PermutationMatrix <: AbstractMatrix{Bool}
p::Vector{Int}
end
Base.size(P::PermutationMatrix) = (length(P.p), length(P.p))
Base.getindex(P::PermutationMatrix, i::Integer, j::Integer) = i == P.p[j]
Base.:*(P::PermutationMatrix, A::AbstractMatrix) = A[P.p, :]
Base.:*(A::AbstractMatrix, P::PermutationMatrix) = A[:, P.p]
julia> P = PermutationMatrix([2, 1, 4, 3])
4×4 PermutationMatrix:
0 1 0 0
1 0 0 0
0 0 0 1
0 0 1 0
julia> A = Matrix(reshape(1:16, 4, 4))
4×4 Matrix{Int64}:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> P * A
4×4 Matrix{Int64}:
2 6 10 14
1 5 9 13
4 8 12 16
3 7 11 15
julia> A * P
4×4 Matrix{Int64}:
5 1 13 9
6 2 14 10
7 3 15 11