haskell - haskell中多元函数的结果类型

标签 haskell polyvariadic

在研究 Haskell 中的多元函数时,我偶然发现了以下 SO 问题:

How to create a polyvariadic haskell function?

Haskell, polyvariadic function and type inference

我想我会通过实现一个函数来尝试一下,该函数接受可变数量的字符串并将它们连接/合并成一个字符串:

{-# LANGUAGE FlexibleInstances #-}

class MergeStrings r where
    merge :: String -> r
instance MergeStrings String where
    merge = id
instance (MergeStrings r) => MergeStrings (String -> r) where
    merge acc = merge . (acc ++)

如果我使用至少一个字符串参数调用 merge 并且我提供最终类型,那么到目前为止这有效。

foo :: String
foo = merge "a" "b" "c"

省略最终类型会导致错误,即编译以下内容

bar = merge "a" "b" "c"

结果

test.hs:12:7: error:
    • Ambiguous type variable ‘t0’ arising from a use of ‘merge’
      prevents the constraint ‘(MergeStrings t0)’ from being solved.
      Relevant bindings include bar :: t0 (bound at test.hs:12:1)
      Probable fix: use a type annotation to specify what ‘t0’ should be.
      These potential instances exist:
        instance MergeStrings r => MergeStrings (String -> r)
          -- Defined at test.hs:6:10
        instance MergeStrings String -- Defined at test.hs:4:10
    • In the expression: merge "a" "b" "c"
      In an equation for ‘bar’: bar = merge "a" "b" "c"
   |
12 | bar = merge "a" "b" "c"
   |

这个错误信息很有意义,因为我可以很容易地想到,例如

bar :: String -> String
bar = merge "a" "b" "c"

baz = bar "d"

不是将 bar 呈现为单个字符串,而是呈现为接受并返回一个字符串的函数。

有没有办法告诉 Haskell 结果类型必须是 String 类型?例如,Text.Printf.printf "hello world" 的计算结果为类型 String 而无需显式定义。

最佳答案

printf 由于 type defaulting 而无需类型注释即可工作在 GHCi 中。允许您在不指定具体类型的情况下评估 show $ 1 + 2 的相同机制。

GHCi tries to evaluate expressions of type IO a ,因此您只需要为 MergeStrings 添加适当的实例:

instance (a ~ ()) => MergeStrings (IO a) where
    merge = putStrLn

关于haskell - haskell中多元函数的结果类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62114605/

相关文章:

haskell - Intero 始终安装独立的 GHC

http - 是否可以在 Happstack 中匹配 PATCH 请求?

haskell - 具有IO的Haskell多变量函数

haskell - Haskell中的可变参数绑定(bind)

haskell "Apply"?

database - Haskell 可以伪装成数据库吗?如果可以,怎么做?

unix - Cabal 未能安装 unix-2.7.0.0

performance - Data.Vector.Unboxed.Mutable.MVector 的索引真的这么慢吗?

haskell - Haskell printf 是如何工作的?