4 ms·
Haskell: add1 = (+1) > add1 23 24 > add1 2.01 3.01 > add1 "0" No instance found... But that error is at compile time.
by deckiedan 10y ago
Haskell:
add1 = (+1)
> add1 23
24
> add1 2.01
3.01
> add1 "0"
No instance found...
But that error is at compile time.
- eggy 10y agoAnd in J: add1 =: >: add1 1r3 4r3 add1 0 1
- photon-torpedo 10y agoRight, with currying it can be even more terse. And getting the error at compile time is actually preferable. My Haskell is very rusty, but IIRC it will deduce that the argument to add1 must be Num, because of the type constraint on (+): (+) :: Num a => a -> a -> a So if I'm not mistaken, your add1 is equivalent to my addone2, i.e. incorporating a type constraint based on the type hierarchy. I'm curious: what's the equivalent of my addone3 in Haskell? How would you define add1 so that it also works on a type T later defined by the user, with T just supporting addition but T not subtype of Num? Do you need to define your own addition function (acting as a proxy for (+) for Num types)?
- mmalone 10y agoI'm still pretty new to Haskell, but I think there are several ways. The equivalent to your addone3 would be some sort of Template Haskell incantation. Template Haskell gives you lisp-style hygienic macros that are expanded and type checked at compile time (except more complicated because of the more complicated semantics and AST). Haskell also provides a ton of options for generic programming that provide similar power (still statically typed). GADTs (Generalized Algebraic Data Types) might be of use here. There are also existential types and type classes. What you probably really want though is a dependently typed language like Idris or Agda. If you're not familiar, here's the one liner: Java generics are types that depend on types (like a List of Bools). Dependent types are types that can depend on values (like a List of exactly 3 Bools). So in theory you should be able to define the type you're looking for here, but I don't know what the concrete syntax would be. The problem with dependently typed languages right now is that the surface languages and concepts tend to be hard for people to grok. Personally I think meta-programming facilities and DSLs will help with this. Ther are lots of languages heading in that direction.
- kazinator 10y agoI wrote myself a perfectly functioning multi-entry accounting system over last weekend in my own dialect of Lisp for my self-employment venture. It's stuffed full of real data spread over nine accounts and lets me see a ledger report over any time period at a glance: all the debits and credits with running balances and so on. I can easily obtain the information to do all taxes and whatnot. It generates beautiful HTML+CSS invoices with a nice SVG logo. It's nicely object-oriented with classes and methods for everything: ledger, account, transaction, increment, invoice. I overloaded a cluster of math functions in a separate package so they work over a money type. It has self-checks against accounting errors. Working code poured out almost as fast as I can type. If I had to think about some propeller-head academic dependent type nonsense, I'd still be writing it come March 2018. > The problem with dependently typed languages right now is that the surface languages and concepts tend to be hard for people to grok. Anything hard to grok is a regression in tooling. Why would I want to grok something difficult, when I'm finding programming easy and don't have any issues with getting the desired behavior out of the machine. All I want to be grokking is how the bits of the run-time representation in the machine are coming together to solve whatever is being solved.
- mmalone 10y agoI actually agree, for the most part. I'm not advocating for Haskell or any of the other languages I mentioned, per se. I've spent time with lots of languages and there are things I like and don't like about all of them. If you forced me to write down my top 10 favorite languages, there would undoubtedly be several Lisps near the top. If you're programming a single computer the existing languages and tooling are good. What I'm interested in is distributed compute and compute over heterogenous architectures (CPUs, GPUs, FPGAs, microcontrollers, etc). For simplicity, let's limit ourselves to the simple case of HTTP-based service-oriented systems (or microservices). The state of the art has us spending a lot of time considering serialization, protocols, communication failures, managing identities, making authorization decisions, routing, etc. Things that should be completely orthogonal to the problem we're trying to solve end up being tightly coupled with our business logic. This becomes exponentially harder to manage as you add languages to your stack. There is a lot of research around solving these problems. Unfortunately, all of it starts with a formal system that is "declarative" (or at least "algebraic") and doesn't mesh well with existing popular languages and tooling. Personally, I think we need to come up with a solution that lets us keep the existing tools that are good for programming a single component, and use some of this newer technology to build a smarter platform / underlay. The bridge between the existing languages and this underlay would be DSLs. Or, more precisely, "abstract languages" that can be implemented as DSLs in a variety of programming languages and may or may not have their own concrete syntax (think SQL+ORMs). Sort of vague, I know, but hopefully that kind of makes sense?
- deckiedan 10y agohttp://stackoverflow.com/questions/39215103/ghc-overlapping-instances-when-generalising-addition http://stackoverflow.com/questions/39215103/ghc-overlapping-...