简体   繁体   English

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

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

In Haskell (GHC), how can one obtain the type signature of the list of functions shown below? 在Haskell(GHC)中,如何获得下面所示功能列表的类型签名?

[tail,init,reverse]

I unsuccessfully tried using the typeOf function of the Data.Typeable module. 我尝试使用Data.Typeable模块的typeOf函数失败。 Specifically, I try to run the following Haskell script: 具体来说,我尝试运行以下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) ]

However, GHC responds with the following error: 但是,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>

Update: The following HUnit test case isn't quite what I wanted, but I did get it to pass (based on David Young's suggestion). 更新:以下HUnit测试用例不是我想要的,但我确实通过了(基于David Young的建议)。 This test case at least forces the compiler to confirm that [tail,init,reverse] is of type [ [a] -> [a] ] . 该测试用例至少迫使编译器确认[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

You don't need a unit test to check a function's type. 您不需要单元测试即可检查函数的类型。 A unit tests runs after the code has been compiled, it's a dynamic test. 单元测试是在代码编译后运行的,这是一个动态测试。 However, type checking is a static test: all types are tested during the compilation of your program. 但是,类型检查是一种静态测试:所有类型都在程序编译期间进行测试。 Therefore, we can use GHC as a minimal static type checker and reduce your program to: 因此,我们可以将GHC用作最小的静态类型检查器,并将您的程序简化为:

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

You don't even need that test anymore the moment you actually test your functions with real data, because that application will (statically) test the function's type too. 在使用实际数据实际测试函数时,您甚至不需要测试,因为该应用程序也将(静态)测试函数的类型。

Remember, Haskell is a statically typed language. 请记住,Haskell是一种静态类型的语言。 The types are checked during compilation, before your code is run. 在运行代码之前 ,在编译过程中检查类型。 Any type checking unit-test is therefore more or less a code-smell, because it can only pass. 因此,任何类型检查单元测试或多或少都是代码气味,因为它只能通过。

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

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