繁体   English   中英

在Haskell脚本中,如何以编程方式获取函数的类型签名?

[英]In a Haskell script, how does one programatically obtain the type signature of a function?

在Haskell(GHC)中,如何获得下面所示功能列表的类型签名?

[tail,init,reverse]

我尝试使用Data.Typeable模块的typeOf函数失败。 具体来说,我尝试运行以下Haskell脚本:

import Data.Typeable
import Test.HUnit
myTest = TestCase
          ( assertEqual "\n\nShould have been \"[[a] -> [a]]\""
            "[[a] -> [a]]"
            (show ( typeOf [tail,init,reverse] )) )
tests = TestList [ (TestLabel "myTest" myTest) ]

但是,GHC会出现以下错误:

C:\>ghci my_script.hs
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( my_script.hs, interpreted )
my_script.hs:7:21: error:
    * No instance for (Typeable a0) arising from a use of `typeOf'
    * In the first argument of `show', namely
        `(typeOf [tail, init, reverse])'
      In the third argument of `assertEqual', namely
        `(show (typeOf [tail, init, reverse]))'
      In the first argument of `TestCase', namely
        `(assertEqual
            "\n\
            \\n\
            \Should have been \"[[a] -> [a]]\""
            "[[a] -> [a]]"
            (show (typeOf [tail, init, reverse])))'
Failed, modules loaded: none.
Prelude>

更新:以下HUnit测试用例不是我想要的,但我确实通过了(基于David Young的建议)。 该测试用例至少迫使编译器确认[tail,init,reverse]的类型为[ [a] -> [a] ]

import Data.Typeable
import Test.HUnit
myTest = TestCase
          ( assertEqual "\n\nShould have been 3"
            3
            ( length ( [tail,init,reverse] :: [[a]->[a]] ) ) )
tests = TestList [ (TestLabel "myTest" myTest) ]
C:\>my_script.hs
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( my_script.hs, interpreted )
Ok, modules loaded: Main.
*Main> runTestTT tests
Cases: 1  Tried: 1  Errors: 0  Failures: 0

您不需要单元测试即可检查函数的类型。 单元测试是在代码编译后运行的,这是一个动态测试。 但是,类型检查是一种静态测试:所有类型都在程序编译期间进行测试。 因此,我们可以将GHC用作最小的静态类型检查器,并将您的程序简化为:

main :: IO ()
main = return ()
  where
    tailInitReverseAreListFunctions :: [[a] -> [a]]
    tailInitReverseAreListFunctions = [tail, init, reverse]

在使用实际数据实际测试函数时,您甚至不需要测试,因为该应用程序也将(静态)测试函数的类型。

请记住,Haskell是一种静态类型的语言。 在运行代码之前 ,在编译过程中检查类型。 因此,任何类型检查单元测试或多或少都是代码气味,因为它只能通过。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM