4 ms·
What's the equivalent of -- zs' = [Just 2, Nothing, Just 4] zs' = (fmap . fmap) (+1) [Just 1, Nothing, Just 3] in C?
by rgoulter 7y ago
What's the equivalent of
-- zs' = [Just 2, Nothing, Just 4]
zs' = (fmap . fmap) (+1) [Just 1, Nothing, Just 3]
in C?
- FeepingCreature 7y agoAt least on the D side: Nullable!int[] zs = [2.nullable, Nullable!int(), 4.nullable]; // no partial application, and // separate template parameters and runtime parameters // so (fmap . fmap) (+1) is one function Nullable!int[] zs2 = map!(apply!(i => i + 1))(zs).array; The C version probably has a lot more function pointers, and may use nonstandard compiler functions like closures. But in principle you could do the same thing.
- sweeneyrod 7y agoThat's not the same, it's just composing the maps for arrays and nullables. The whole point of fmap is that you can write (fmap . fmap) (+1) [Just 1, Nothing, Just 3] but also (fmap . fmap) (+1) Just [1, 3], rather than using (list_map . option_map) (+1) and (option_map . list_map) (+1) respectively. The usefulness of this is arguable. In my biased opinion as someone who favours OCaml (which lacks the typeclasses that allow this) over Haskell, I think it's minimal. While it's definitely useful to recognise that lists, options and promises are examples of the same pattern, I don't this generalisation has many benefits in code (at least in MLs where you don't need this pattern just to print things).
- FeepingCreature 7y ago> The usefulness of this is arguable. And I have argued it on D, and we very deliberately did not go with the range semantics. Optional types are not ranges unless you're compulsively hunting for forced commonality. Might as well treat any value as a range of 1.
- feanaro 7y agoThey are not ranges, but they are functors, as are ranges. The commonality between ranges and option types is that they are both functors and this is not forced.
- FeepingCreature 7y agoI guess I subscribe to the school of thought that says that types are supposed to model the domain information of the data they represent. I know what it means when a value is either provided or not provided. I know what it means when a field has one of a number of values. I don't know what it's supposed to represent, in a domain sense, when a value is "a functor."
- feanaro 7y agoNote that a value is not a functor, its type is. When some type T is a functor, this means that T contains (as part of its definition) a type variable which you can change by mapping functions over values of type T. For instance, the list type `[a]` and the option type `Maybe a` are both functors. The associated type variable is `a`. This type variable can be manipulated by using `map` to apply some function `f : a -> b` over values of both `[a]` and `Maybe a`. Applying `f` using `map` over such values would yield values of new types, namely `[b]` and `Maybe b`. This implies that `map f` is a general way of expressing the application of function `f` to values of any functor type. The notion of functor types is therefore supposed to represent any kind of abstract containment relationship. In other words, any time you have the situation of an arbitrary type being wrapped in some kind of "wrapper" (list of..., set of..., range of..., optionally present..., etc), you are dealing with a functor type. The functor abstraction allows you to apply ordinary functions to such values in a uniform way, regardless of which particular kind of container or wrapper we are dealing with.
- FeepingCreature 7y agoYeah I get that, I don't get what it is supposed to say about the domain. Ie. the real-world facts that the data type models. That's why I approve of separating option types and range types. "Apply to value if it exists" seems like a different operation from "apply to all values"; even if it's the same one on a deeper level, it feels like it's the same on a level deeper than the reality it represents.