Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It just means that ‘a’ must be a Number [0]. In this context, I believe satisfies means that it implements the things defined in the ‘minimum definition’ in the link below. If you’re familiar with Go, it’s similar to something implementing an interface.

[0] https://hackage.haskell.org/package/base-4.20.0.1/docs/GHC-N...



well why does Num then come before a ? If a :: Num would mean a is a value of type Num, why does this "satisfies" constraint does not follow the pattern?


Technically, `a :: Num` would be declaring, or defining that `a` is of type `Num`. After you see `a :: Num`, you can assume from then on as you're reading the program that `a` has type `Num`; if something is incompatible with that assumption it will result in a compiler error. This is different from `Num a`, which is making the assertion that `a` is of type `Num`, but that assertion may evaluate as true or false. It's similar to how assignment is different from equality, so that most programming languages with C-style syntax make a distinction between `=` and `==`.

There's also the fact that `Num` is technically not a type, but a type class, which is like a level above a type: values are organized into types, and types are organized into classes. Though this is more of a limitation of Haskell: conceptually, type classes are just the types of types, but in practice, the way they're implemented means they can't be treated in a uniform way with ordinary types.

So that's why there's a syntactic distinction between `Num a` and `a :: Num`. As for why `Num` comes before `a`, there's certainly a reasonable argument for making it come after, given that we'd read it in English as "a is a Num". I think the reason it comes before is that it's based on the usual function call syntax, which is `f x` in Haskell (similar to `f(x)` in C-style languages, but without requiring the parentheses). `Num` is kind of like a function you call on a type which returns a boolean.


> If a :: Num would mean a is a value of type Num

`a` is the type. Num is a `class`.

Here's an example. x is an Int32 and y is an Int64. If they had type Num, then this would be valid:

  add :: Num -> Num -> Num           -- Not valid Haskell
  add x y = x + y
However it's not valid, because you can't add an Int32 and an Int64:

  add :: Int32 -> Int64 -> ?     -- Doesn't compile
  add x y = x + y
But you can add Nums together, as long as they're the same type. You indicate they're the same type by using the same type variable 'a':

  add :: a -> a -> a      -- Doesn't compile
  add x y = x + y
But now the above complains because you used (+) which belongs to Num, so you have to declare that these `a`s can (+) because they're Nums.

  add :: Num a => a -> a -> a
  add x y = x + y
And it comes out shorter than your suggestion of putting the constraints afterward:

  add :: (a :: Num) -> (a :: Num) -> (a :: Num)       -- Not valid Haskell
  add x y = x + y




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: