不能匹配两个相同的类型

Cannot match two identical types

提问人:Futarimiti 提问时间:11/8/2023 更新时间:11/8/2023 访问量:36

问:

由于我是伊德里斯的新手,我真的不知道如何正确解决这个问题,所以我会讲述我的故事。

我正在实现一个类型安全的 sprintf 函数,具有以下类型签名:

sprintf : (s: String) -> typeListToFunc String (corresArgs (toPrintf (unpack s)))

其中,一大堆东西基本上是在字符串中寻找 printf 说明符,并在函数方面生成所需的参数。例如,would give ,并且会简单地给出 。"%c%f%d"Char -> Double -> Int -> String""String

尽管此实现工作正常,但无法通过类型检查来通过测试。下面简要介绍一下:

import Specdris.Spec
import Sprintf

specSuite : IO ()
specSuite = spec $ do
  describe "Fixed tests" $ do
    it "Should accept no arg when no fmt" $ do
      sprintf "" `shouldBe` ""  -- this is line 13

特别是,伊德里斯找不到 和 之间的匹配项:StringtypeListToFunc String (corresArgs (toPrintf (unpack "")))

Type checking ./Sprintf.idr
Type checking ./SprintfSpec.idr
SprintfSpec.idr:10:13-24:108:
   |
10 | specSuite = spec $ do
   |             ~~~~~~~~~ ...
When checking right hand side of specSuite with expected type
        IO ()

When checking an application of function Specdris.Data.SpecResult.SpecResultDo.>>=:
        Can't find implementation for Show (typeListToFunc String (corresArgs (toPrintf (unpack ""))))

        Possible cause:
                SprintfSpec.idr:13:18-27:When checking argument expected to function Specdris.Expectations.shouldBe:
                        Type mismatch between
                                String (Type of "")
                        and
                                typeListToFunc String (corresArgs (toPrintf (unpack ""))) (Expected type)

                        Specifically:
                                Type mismatch between
                                        String
                                and
                                        typeListToFunc String (corresArgs (toPrintf []))

如前所述,它们实际上是同一类型:

$ idris Sprintf.idr
*Sprintf> typeListToFunc String (corresArgs (toPrintf (unpack "")))
String : Type

是的,我真的很困惑为什么伊德里斯不能解决这个问题。FWIW 如果有人想详细查看,我已将我的源文件和测试规范放在 GitHub 上

printf 错误 检查类型 不匹配 idris

评论


答:

0赞 Futarimiti 11/8/2023 #1

事实证明,以前来过的人已经意识到了这个问题。在此线程中引用 Voile 的话:

每个数据类型和类型级函数都必须公开导出,以便测试模块看到它们(测试模块也是如此),因此 %access public export 应该是几乎所有情况下的默认值。这让人们(阅读:解决 Idris kata 时的我)因为例如 Try It Online 不需要它(代码与 Main.main 位于同一模块中)。

添加解决了该问题。%access public export

评论

0赞 joel 11/8/2023
%access public export对于 Codewars 来说很好,因为它是一个单文件应用程序,但对于任何更大的应用程序,它似乎过于宽松 - 默认情况下,您将公开模块中所有内容的实现。我想是口味问题