haskell - 此功能的正确签名是什么?

标签 haskell

此代码无法编译并出现此错误

src/JsonParser.hs:33:37-62: error:
    * Couldn't match type `b1' with `b'
      `b1' is a rigid type variable bound by
        the type signature for:
          resultantRunParse :: forall b1. String -> Maybe (String, b1)
        at src/JsonParser.hs:29:5-52
      `b' is a rigid type variable bound by
        the type signature for:
          fmap :: forall a b. (a -> b) -> Parser a -> Parser b
        at src/JsonParser.hs:27:11-42
      Expected type: Maybe (String, b1)
        Actual type: Maybe (String, b)

代码:

import Prelude

newtype Parser a = Parser
  { runParser :: String -> Maybe (String, a)
  }

instance Functor Parser where
  fmap :: (a -> b) -> Parser a -> Parser b
  fmap f (Parser p) = Parser resultantRunParse where
    -- THIS FUNCTION TYPE DECLARATION IS THE PROBLEM
    -- IF I REMOVE THE TYPE DECLARATION, IT WORKS
    resultantRunParse :: String -> Maybe (String, b)
    resultantRunParse input = 
      case p input of
        Nothing -> Nothing
        Just (remaining, parsed) -> Just (remaining, f parsed)

我尝试了签名 resultantRunParse::forall b1。错误消息中建议的 String -> Maybe (String, b1) 也没有用。

此外,制作 resultantRunParse = undefined 并保持类型签名也有效。很奇怪!

这个函数的正确签名是什么?

最佳答案

类型签名必须包含b,但它必须与封闭函数中使用的b 相同。如果没有作用域类型变量,这是不可能的:

https://wiki.haskell.org/Scoped_type_variables

为此,请在文件顶部添加评论:

{-# LANGUAGE ScopedTypeVariables #-}

然后,在封闭函数的类型签名中使用显式 forall b.

如果没有作用域类型变量,就无法在类型签名中写入 b 并使其与使用的相同 b在封闭函数中。

(我个人的建议是不要在这里使用类型签名。这是没有必要的。)

关于haskell - 此功能的正确签名是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68248606/

相关文章:

haskell - 用于生成 Haskell 函数依赖(控制流)图的工具?

linux - 如何在emacs中bash终端的 "line run"模式下输入EOF?

haskell - ST有多严格

haskell - 如何使用 MonadRandom?

haskell - 在 main 中执行简单 I/O 的更好方法

algorithm - 寻找唯一的(只出现一次)元素haskell

Haskell:lift 与 liftIO

haskell - 省略 Happy 中的剩余输入(Haskell 的解析器生成器)

haskell - 在哪种意义上,守卫比命令式-if 更好? (haskell 新手)

haskell - Haskell/Yesod 中的分组复选框