3 ms·
I'm targeting only WASM at the moment. I wish I could get into Haskell, but I just can't read it. I really can't parse what's going on with types like `Result e
by spankalee 9mo ago
I'm targeting only WASM at the moment. I wish I could get into Haskell, but I just can't read it. I really can't parse what's going on with types like `Result e t (Either e t)`.
- hutao 9mo agoThe `Either a b` type in Haskell is equivalent to the `Result<T, Error>` type in other languages. The only difference is in the naming: "Result" semantically implies error handling, while "Either" implies a more general usage as the alternative between two options. Either and Result are the binary sum type (the disjoint union between two types). In Haskell, Either is defined as data Either a b = Left a | Right b Note that in Haskell, type parameters are lowercase. Source code: https://gitlab.haskell.org/ghc/ghc/-/blob/3f5e8d80b32063d265aeead6b62604c9ad4a34da/libraries/ghc-internal/src/GHC/Internal/Data/Either.hs#L127 https://gitlab.haskell.org/ghc/ghc/-/blob/3f5e8d80b32063d265... Contrast the definition of the Result type in Swift: public enum Result<Success: ~Copyable & ~Escapable, Failure: Error> { /// A success, storing a `Success` value. case success(Success) /// A failure, storing a `Failure` value. case failure(Failure) } Source code: https://github.com/swiftlang/swift/blob/256ff127c93d7e59a75f819372602eca0f97c788/stdlib/public/core/Result.swift https://github.com/swiftlang/swift/blob/256ff127c93d7e59a75f... I'm not sure what the parent commenter meant when they claimed that "Result <e, t> of yours is a Result (e, t) in Haskell." In Haskell, `(e, t)` would be the pair type (the binary product type).
- thesz 9mo ago> The `Either a b` type in Haskell is equivalent to the `Result<T, Error>` type in other languages. The only difference is in the naming: This is false and misleading. The Result <E, T> usually (C#, at the very least, most probably C++ and many other languages) should always be fully instantiated. One usually cannot construct a type "function" like Result <E,> that needs a single type argument to instantiate a full type. The partial application on type level is not there in most languages, including Rust (a result of a little googling). The Haskell's Either type can be instantiated to Be a two-type-arguments function, one type argument function and, finally, a fully instantiated type like Either String Int. This means that Result <E, T> type effectively has a single type argument, namely pair of types. The Either type has two type arguments and can be partially applied.
- hutao 9mo agoYou are right, in Haskell type constructors may be partially applied. In my opinion, this feature has less to do with any fundamental difference between `Either` in Haskell and `Result` in other languages, and more to do with Haskell's more powerful type system. In the same way, the pair type (a, b) in Haskell is also different from the pair types in other languages. This feature is called "higher-kinded types." In particular, higher-kinded types are necessary to abstract over functors (or functions from types to types, * -> *). The list type constructor is a functor, and the partially applied type constructor `Either a` is also a functor. However, in languages without higher-kinded types, type variables can only be "ground types" (of kind *). I don't agree with this statement: > This means that Result <E, T> type effectively has a single type argument, namely pair of types. The Either type has two type arguments and can be partially applied. The Result<T, E> type still takes two type arguments. The main distinction, in my view, is that Haskell allows types to be "higher-order." In fact, to be really pedantic, you could argue that the `Either` type in Haskell really takes one type argument, and then returns a function from types to types (currying). This is kind of like the type-level equivalent to how many programming languages support some notion of function or procedure (and functions may have multiple arguments), but only more modern languages support higher-order functions, or allow variables to be functions.
- thesz 9mo agoThe paper about type classes [1] includes exceptions as an example. [1] https://web.cecs.pdx.edu/~mpj/pubs/springschool95.pdf https://web.cecs.pdx.edu/~mpj/pubs/springschool95.pdf This [2] paper generalizes exceptions, allowing them to be first class citizens of a language and even to be a exceptions-as-a-library. [2] https://raw.githubusercontent.com/nbenton/nbenton.github.io/master/monadsandeffectsfinal.pdf https://raw.githubusercontent.com/nbenton/nbenton.github.io/... In (not only) my opinion, Haskell's greatness is in "what is a language feature in most languages is a library in Haskell." One can model type system of a language by embedding it as a library into a Haskell and then develop it further as a standalone language if one prefers such path. I did that embed-as-library thing several times. It was of great help, especially in the embedded systems and hardware circuits domains.