Earlier quoted context omitted.
> law-abiding implementations Are you referring to category laws?
Lots of typeclasses have associated "laws" that well-behaved instances are expected to abide by.
Thinking in Types
81–90 of 124 posts
Re: Thinking in Types
#82Earlier quoted context omitted.
Lots of typeclasses have associated "laws" that well-behaved instances are expected to abide by.
But these are not enforceable by the type system (at least in Haskell), kind of supporting my point that types alone are rarely sufficient :)
Re: Thinking in Types
#83Earlier quoted context omitted.
Haskell is used in the NYTimes special features group that deploys 60+/yr web apps. http://www.infoq.com/presentations/haskell-newsroom-nyt tldw: - RoR shop, too slow and can't afford to scale simply by spinning up more AWS instances. - Haskell type system results in fewer bugs, less downtime than RoR. - Haskell's Conduit library is great for information flow (e.g. scanning Twitter firehose for breaking stories). - S…
It's worth pointing out that the presenter's first language was Haskell and he's been coding in it for over a decade. LYAH won't get you from apples to expert in weeks, much less months; more likely years. Consider me skeptical -- needing to build the latest and greatest of Haskell [7.8] from source on a modern Linux distro (CentOS binary with antiquated libgmp.so.3 dependency, seriously?) is a gigantic PITA compared…
Re: Thinking in Types
#84I'm not sure that this works in more general cases, though. If I have a more general game with more objects of more types in it, adding each type to the render function is going to get old. In object oriented programming, I'd just call render() on each entry in the list of game objects. But this approach is going to lead me to: - render each entry in the list of Foo objects - render each entry in the list of Bar obje…
Re: Thinking in Types
#85> If we’re careful in our module exports, a change like this can be done in a backward-compatible way. Such an approach is outlined here ( http://www.yesodweb.com/blog/2011/10/settings-types ). The problem with this import solution is that almost nobody actually does it! Nearly every module you will ever import exposes most of the constructors of the ADTs they define - because Haskell encourages it - it's much simple…
Re: Thinking in Types
#86Seeing so much stuff about Haskell lately, but there seems to be a curious dearth of actual software written in it, if it's so great. How is it that janky hacked together languages like JS and PHP have huge numbers of projects built with them, while a supposedly superior language like Haskell is mostly academic? If it really makes you that much faster, where are the apps?
Honestly, it seems to me like if you don't understand category theory and type theory well, using Haskell will be either hard or impossible. That's what people who are into Haskell are into, and they seem to be a relatively rare breed. (I have a lot of trouble understanding these subjects, though I continue to try. I still don't know what the hell a monad really is.)
In programming, a monad is a particular design pattern, which is exposed in a particular interface (appropriately called Monad) in Haskell. The design pattern supports a certain way of combining things. The fact that so many disparate things support this interface (State, IO, Software Transactional Memory, Readers, Writers, Continuations...) means that all of the code we write that generically talks to that interface can talk about any of those things, and that's pretty powerful. The fact that one of those things is, in a certain sense, voodoo (IO) shouldn't lead you to think they all are - Monad is just an interface for combining things according to certain patterns.
Re: Thinking in Types
#87I'm not sure that this works in more general cases, though. If I have a more general game with more objects of more types in it, adding each type to the render function is going to get old. In object oriented programming, I'd just call render() on each entry in the list of game objects. But this approach is going to lead me to: - render each entry in the list of Foo objects - render each entry in the list of Bar obje…
In this case, a common pattern is to copy the OO concept of casting. For example, instead of having:
class Render a where
render :: a -> IO()
we could have: class Renderable a where
toRender a -> Render
along with: data Render = ...
render :: Render -> IO()
render r = ...
This leads to some noise with needing to put a bunch of toRender functions in a short amount of code, but this problem does not get worse as complexity increases.Re: Thinking in Types
#88I'm not sure that this works in more general cases, though. If I have a more general game with more objects of more types in it, adding each type to the render function is going to get old. In object oriented programming, I'd just call render() on each entry in the list of game objects. But this approach is going to lead me to: - render each entry in the list of Foo objects - render each entry in the list of Bar obje…
data GameEntity = GameEntity
{ render :: IO ()
, getPosition :: Point
, setPosition :: Point -> GameEntity
}
makeBall :: Point -> GameEntity
makeBall pos = GameEntity { render = myRender
, getPosition = pos
, setPosition = mySetPos
}
where myRender = {- draw the ball somehow -}
mySetPos newPos = makeBall newPos
{- and similar for makePlayer -}
That means that the rendering code will look like renderAll :: [GameEntity] -> IO ()
renderAll allEntities = mapM_ render allEntities
main = do
pl = makePlayer 1 (0, 5.0)
p2 = makePlayer 2 (10.0, 5.0)
b = makeBall (5.0, 5.0)
{- ... -}
renderAll [p1, p2, b] -- type-checks correctly now
What I've done is used a record type to encode the interface that it's supposed to expose, while hiding exactly what the particular implementations of the interface are. It's also nicely extensible; if I wanted to add in some other kind of entity—say, a turtle—all I'd need to do is add a function like makeTurtle :: Point -> ShellColor -> TurtleDisposition -> GameEntity
and nothing else need be changed.Re: Thinking in Types
#89I'm getting tired of reading: > This is why we hear that Haskell reprise if it compiles, it works. If this were true then functions would not need bodies, you would just define their signatures and move on with life. The truth is that even with its superb type system, Haskell still needs to run your code. Your code might be statically correct but its runtime is up to you. I would prefer it if people rephrased this cl…
And you know what I am tired of reading, Cedric Buest? You trolling every programming language discussion with fake names and sock puppets relating your fake made up experiences with functional programming. Do you have no dignity?
Re: Thinking in Types
#90> If we’re careful in our module exports, a change like this can be done in a backward-compatible way. Such an approach is outlined here ( http://www.yesodweb.com/blog/2011/10/settings-types ). The problem with this import solution is that almost nobody actually does it! Nearly every module you will ever import exposes most of the constructors of the ADTs they define - because Haskell encourages it - it's much simple…