How? By building the structure/hard stuff first and letting the compiler verify it while leaving out the uninteresting parts.
A very simple example. Let's say you have some data model with people, addresses, whatever. You want to see what you need to do to get a list of addresses for some group of people.
You start by defining the structure of your data model (this can depend on DB schema, business requirements, whatever):
data Person = Person { name :: String, city :: String }
data Address = Address { city :: String, zipcode :: String, street :: String }
Now, go straight to the hard part. No need to fuck around with DB connections, mock data, whatever: getAddresses :: [Person] -> [Address]
getAddresses = undefined
Leave out the implementation for now. So probably we are gonna need a way to get an Address for a Person. Ok: addressForPerson :: Person -> Address
addressForPerson = undefined
Again, leave out the implementation. Now go back to `getAddresses` and see if we can implement it now: getAddresses = map addressForPerson
Cool, the compiler doesn't complain. So far we've verified that if we have a function like `addressForPerson` we can safely assume that our design is going to work.Now we can go back to `addressForPerson` and implement that. But turns out, we only have a city stored in Person, so the best we can do is get back a list of potential addresses for each person. So we need to adjust that type signature:
addressForPerson :: Person -> [Address]
addressForPerson = undefined
Leave out implementation, it's trivial so no need to spend time on it now. But now the compiler complains that `getAddresses` doesn't make sense anymore! We are saying that, having a list of people, we can get a list of addresses, but that's not true anymore. We found out that we can only get a list of potential addresses, so we have to adjust the type signature. getAddresses :: [Person] -> [[Address]]
Now every use of `getAddresses` will have to be adjusted to the new requirements. Etc etc.Granted, this is a very simple example, but I hope it illustrates how static languages facilitate extremely fast prototyping. Sure, a Lisp REPL is very very nice, but in my personal experience it's no match for a type system. We didn't even have to mock data to start experimenting!
(And yes, Haskell, OCaml, PureScript, Elm etc all have a REPL too).