Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell printf返回了什么?_Haskell - Fatal编程技术网

Haskell printf返回了什么?

Haskell printf返回了什么?,haskell,Haskell,我正在学习Haskell,这是我理解语法的第一步。不幸的是,我的日子很难过,语言参考对我没有帮助 我试着做:键入(行长1 2 3 4),我有红色的,但是它使用了含义模糊的符号而不是单词。所以,我被困住了,需要帮助 简单地说:我应该写什么来代替? line_length :: Integer -> Integer -> Integer -> Integer -> ??? line_length ax ay bx by = printf ("The l

我正在学习Haskell,这是我理解语法的第一步。不幸的是,我的日子很难过,语言参考对我没有帮助

我试着做
:键入(行长1 2 3 4)
,我有红色的,但是它使用了含义模糊的符号而不是单词。所以,我被困住了,需要帮助

简单地说:我应该写什么来代替

line_length :: Integer -> Integer -> Integer -> Integer -> ???
line_length ax ay bx by =
            printf ("The length of the line between the points" ++
            "(%d,%d) and (%d,%d) is %.5f\n") ax ay bx by
            ((((fromIntegral (ax - bx)) ** 2.0) +
            ((fromIntegral (ay - by))) ** 2.0) ** 0.5)

当我被类型签名所困扰时,我让Haskell为我做艰苦的工作。就是我

  • 编写不带类型签名的定义
  • 将其加载到ghci中
  • 以交互方式检查Haskell提供的类型
  • 在源文件中复制该签名(确保它是我想要的)

重载的返回类型
printf::PrintfType r=>String->r
可能会有点混乱,但查看可用的
PrintfType
实例会有所帮助:

  • 首先,我们有一个例子:

    instance (PrintfArg a, PrintfType r) => PrintfType (a -> r)
    
    此参数用于允许
    printf
    接受数量可变的参数。这是有道理的,因为使用了curry,但您可能不会认为它是函数的“true”返回类型。有关其工作原理的更多信息,请参阅

  • 那么我们有这个例子,

    instance PrintfType (IO a)
    
    这意味着我们可以将其用作
    IO
    操作。与打印类似,这会将结果打印到标准输出。操作的结果是未定义的,因此您应该忽略它。1

  • 最后

    instance IsChar c => PrintfType [c]
    
    这里的type类主要是为了使它符合Haskell 98。由于
    IsChar
    的唯一实例是
    Char
    ,因此可以将其视为

    instance PrintfType String
    
    但这需要GHC特定的扩展
    FlexibleInstances

    这个实例的意思是,您也可以只返回一个
    字符串
    ,而不打印它,类似于C中的
    sprintf

    > printf "Foo %d\n" 42 :: String
    "Foo 42\n"
    
  • 因此,根据您是要打印结果还是只返回结果,您可以在示例中用
    IO()
    String
    替换

    但是,您的代码还有另一个问题,编译器无法确定您希望最后一个参数是哪种类型,因此您必须通过类型注释来帮助它:

    line_length :: Integer -> Integer -> Integer -> Integer -> String
    line_length ax ay bx by =
                printf ("The length of the line between the points" ++
                "(%d,%d) and (%d,%d) is %.5f\n") ax ay bx by
                ((((fromIntegral (ax - bx)) ** 2.0) +
                ((fromIntegral (ay - by))) ** 2.0) ** 0.5 :: Double)
    

    1这样做是为了避免扩展。通过扩展,我们可以编写
    实例PrintfType(IO())
    ,结果是
    ()

    如果您想学习Haskell,Printf不是一个好的开始。您希望返回什么类型的
    行长度
    ?顺便说一句,
    (^2)
    优于
    (**2)
    sqrt
    优于
    (**0.5)
    。对于试图理解语法来说,语言参考当然不是很好的学习来源。您是否尝试过简单的书籍/教程,例如,或?我还想引用您链接到的文档:“返回值为String或(IO a)。”“我实际上不需要从行长度返回任何内容”??在Haskell中,不需要返回任何内容的函数是完全没有意义的。
    line_length :: Integer -> Integer -> Integer -> Integer -> String
    line_length ax ay bx by =
                printf ("The length of the line between the points" ++
                "(%d,%d) and (%d,%d) is %.5f\n") ax ay bx by
                ((((fromIntegral (ax - bx)) ** 2.0) +
                ((fromIntegral (ay - by))) ** 2.0) ** 0.5 :: Double)