Why is function definition for all types at once not allowed in Haskell?

后端 未结 5 1742
迷失自我
迷失自我 2020-12-10 01:14

This is probably a very basic question, but ...

A function that\'s defined as, say

foo :: a -> Integer

denotes a function from <

5条回答
  •  北海茫月
    2020-12-10 01:45

    For a function a -> Integer there's only one behaviour which is allowed - return a constant integer. Why? Because you have no idea what type a is. With no constraints specified, it could be absolutely anything at all, and because Haskell is statically typed you need to resolve everything to do with types at compile time. At runtime the type information no longer exists and thus cannot be consulted - all choices of which functions to use have already been made.

    The closest Haskell allows to this kind of behaviour is the use of typeclasses - if you made a typeclass called Foo with one function:

    class Foo a where
        foo :: a -> Integer
    

    Then you could define instances of it for different types

    instance Foo [a] where
        foo [] = 0
        foo (x:xs) = 1 + foo xs
    
    instance Foo Float where
        foo 5.2 = 10
        foo _ = 100
    

    Then as long as you can guarantee some parameter x is a Foo you can call foo on it. You still need that though - you can't then write a function

    bar :: a -> Integer
    bar x = 1 + foo x
    

    Because the compiler doesn't know that a is an instance of Foo. You have to tell it, or leave out the type signature and let it figure it out for itself.

    bar :: Foo a => a -> Integer
    bar x = 1 + foo x
    

    Haskell can only operate with as much information as the compiler has about the type of something. This may sound restrictive, but in practice typeclasses and parametric polymorphism are so powerful I never miss dynamic typing. In fact I usually find dynamic typing annoying, because I'm never entirely sure what anything actually is.

提交回复
热议问题