Ok so basically the issue is that ndarray is modeled as a wrapper around a shared_ref, so we can apply the same logic as shared_ptr conceptually. How do you handle const correctness on a shared_ptr?
Well using the template parameter: ```shared_ptr<T> ``` vs ```shared_ptr<const T> ```. Knowing that converting implicitly from 1st to 2nd is allowed but the other way is not.
You can differentiate this way:

```
shared_ptr<T> flat() {...}
shared_ptr<const T> flat() {...}
```

Just have to translate into ndarray now :)