How to define function signatures partially in Haskell?

后端 未结 6 1196
刺人心
刺人心 2021-02-03 17:54

Starting point:

fn :: [a] -> Int
fn = (2 *) . length

Let\'s say we only want to constrain the return value, then we could write:

6条回答
  •  北恋
    北恋 (楼主)
    2021-02-03 18:10

    To specify only the type of an argument, you can write something like

    fn list = 2 * length list
      where
        a :: [Char]
        a = list `asTypeOf` a
    

    So that it is easy to later amend it like, e.g.,

    fn list = 2 * fromIntegral (length list)
      where
        a :: [Char]
        a = list `asTypeOf` a
    

    and have its inferred type change accordingly:

    *Main> :t fn
    fn :: [Char] -> Int
    *Main> :r
    -- changed file reloaded
    *Main> :t fn
    fn :: (Num t) => [Char] -> t
    

    You could use the same contorted technique to specify the return type of a function, perhaps defined in pointfree style, but this is not pretty.

    fn2 list = r
      where
        r :: Int
        r = f list
        f = (2 *) . length
    

    It is also not much different from what you have right now, just keeps the code and the type spec separated.

提交回复
热议问题