Hacker News new | ask | show | jobs
by llmslave2 163 days ago
Agreed. It's often accompanied by the dogma "make invalid states unrepresentable" which sounds good until you start trying to encode into the type system foo.bar being 1-42 unless foo.baz is above 10, where now foo.bar can be -42-1 instead, but if foo.omfg is prefixed with "wtf" then foo.baz needs to be above 20 for its modifiers to kick in.

Yeah good luck doing that in the type system in a way that is maintainable, open to modification, an scales with complexity.

1 comments

You have misunderstood what it means to make invalid states unrepresentable.

    data UnvalidatedFoo = UnvalidatedFoo
      { unvalidatedOmfg :: String,
        unvalidatedBar, unvalidatedBaz :: Int
      }
    
    data ValidatedFoo = ValidatedFoo
      { validatedOmfg :: String,
        validatedBar, validatedBaz :: Int
      }
    
    validate :: UnvalidatedFoo -> Maybe ValidatedFoo
    validate UnvalidatedFoo {..} = do
      when ("wtf" `isPrefixOf` unvalidatedOmfg) $ do
        guard (unvalidatedBaz > 20)
      if unvalidatedBaz > 10
        then guard (unvalidatedBar >= 1 && unvalidatedBar <= 42)
        else guard (unvalidatedBar >= -42 && unvalidatedBar <= 1)
      pure ValidatedFoo {validatedOmfg = unvalidatedOmfg, validatedBaz = unvalidatedBaz, validatedBar = unvalidatedBar}