I love Peaker's answer. To elaborate with a sort of concrete example of how haskell can help you avoid logic bugs as in your physics simulation example:
In code where the types start to to tell you less, e.g. when doing a bunch of number crunching, and you have a signature that looks like:
func :: Int -> Int -> Int -> Int
It's common for the programmer to use a "newtype wrapper" to bring some of the logic into the type system like:
newtype Velocity = Velocity Int
newtype Force = Force Int
newtype Iteration = Iteration Int
Then the type system will catch if you accidentally use the Velocity when what you want is Force, etc.
In code where the types start to to tell you less, e.g. when doing a bunch of number crunching, and you have a signature that looks like:
It's common for the programmer to use a "newtype wrapper" to bring some of the logic into the type system like: Then the type system will catch if you accidentally use the Velocity when what you want is Force, etc.