python - haskell 类型声明的使用方式是否与 python 类/函数文档相同?

标签 python haskell type-declaration

我正在使用“向您学习 haskell 教程”并已到达类型声明部分。我知道它们改变了 GHCI 给你错误消息的方式,但它们是否也影响实际功能的工作方式?如果不是,它本质上是否像在“def someFunction(x):”下面用“””“””编写的 python 函数文档? - 只是一个例子

示例代码:

removeNonUppercase :: [Char] -> [Char]  
removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]

编辑:我问这个是因为教程解释了 haskell 在编译时是类型推断的。

最佳答案

签名不仅仅用于文档(尽管它们对此也非常有用)。它们由编译器强制执行,这意味着通过添加签名,您可以使函数的类型比其他方式更具限制性。玩具示例:

add x y = x + y

addInt :: Int -> Int -> Int
addInt x y = x + y
*Main> :t add
add :: Num a => a -> a -> a
*Main> add 2 3
5
*Main> add 2.1 3.1
5.2
*Main> :t addInt
addInt :: Int -> Int -> Int
*Main> addInt 2 3
5
*Main> addInt 2.1 3.1 -- addInt will not accept non-Ints.

<interactive>:23:8:
    No instance for (Fractional Int) arising from the literal ‘2.1’
    In the first argument of ‘addInt’, namely ‘2.1’
    In the expression: addInt 2.1 3.1
    In an equation for ‘it’: it = addInt 2.1 3.1

除此之外,添加类型签名意味着您将在棘手的情况下得到更好(即更容易理解)的错误,因为编译器将知道您想要实现的目标,而不必自己猜测所有内容。

还有一些情况,如果没有某些签名或其他类型注释的帮助,编译器无法确定类型。也许最简单的例子是:

readAndShow s = show (read s)

如果您尝试在不指定任何类型的情况下使用它...

Foo.hs:6:17:
    No instance for (Show a0) arising from a use of ‘show’
    The type variable ‘a0’ is ambiguous
    Note: there are several potential instances:
      instance (GHC.Arr.Ix a, Show a, Show b) => Show (GHC.Arr.Array a b)
        -- Defined in ‘GHC.Arr’
      instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
      instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus 26 others
    In the expression: show (read s)
    In an equation for ‘readAndShow’: readAndShow s = show (read s)

Foo.hs:6:23:
    No instance for (Read a0) arising from a use of ‘read’
    The type variable ‘a0’ is ambiguous
    Note: there are several potential instances:
      instance (GHC.Arr.Ix a, Read a, Read b) => Read (GHC.Arr.Array a b)
        -- Defined in ‘GHC.Read’
      instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’
      instance (Integral a, Read a) => Read (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Read’
      ...plus 25 others
    In the first argument of ‘show’, namely ‘(read s)’
    In the expression: show (read s)
    In an equation for ‘readAndShow’: readAndShow s = show (read s)
Failed, modules loaded: none.

... 它不会工作。 readString 转换为 some 类型,而 show 则相反。但是,如果没有指定 read s 的类型,编译器将无法判断您要将 String 读取为哪种类型。所以你要么需要指定中间类型...

readAndShowAsInt s = show (read s :: Int)
*Main> readAndShowAsInt "2"
"2"

...或者让其他人为您选择类型:

readAndAdd :: String -> Int -> Int
readAndAdd s y = read s + y
*Main> readAndAdd "2" 3
5

关于python - haskell 类型声明的使用方式是否与 python 类/函数文档相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31549024/

相关文章:

python - 使用 POST 请求的谷歌反向图像搜索

python - OpenCV VideoWriter 写入损坏的视频文件

Python:如何在两列之间的 Pandas 数据框中添加一列?

parsing - 左右递归解析器

python - 根据字符串文字从联合类型创建数据类实例

haskell - Where 子句的最佳实践

haskell - 我误解了约翰休斯的 `foldtree` 怎么样?

typescript - 有没有办法让测试框架 typescript 声明只在 VS Code 的测试文件中解析?

typescript - 导出的变量 X 具有或正在使用来自外部模块 Z 的名称 Y,但无法命名