Haskell错误:'绑定位置的限定名'

aydmsdu9  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(184)

下面是代码:

import qualified View.TreeWidget as TreeWidget

main :: IO ()
main = do
  print $ bla "sdfsd"

bla someString = case someString of
  TreeWidget.name -> True
  "sdfsd" -> False
  _ -> True

TreeWidget.name是在文件TreeWidget.hs中定义的函数,如下所示:

name :: String
name = "tree_list_name"

错误如下:

src/View/Main.hs:8:3: error:
    Qualified name in binding position: TreeWidget.name
  |
8 |   TreeWidget.name -> True
  |   ^^^^^^^^^^^^^^^

1.为什么会发生这种情况?
1.可以做些什么呢?

  • 谢谢-谢谢
bf1o4zei

bf1o4zei1#

当你看到一个小写的模式,这意味着一个变量匹配所有的东西。如果变量没有在右边使用,你也可以使用一个模式通配符(_)。

name -> True

模式变量用作联编程序,您不能用

name -> ..

name :: String
name = "tree_list_name"

这也意味着你不能从其他模块引用模式变量,而TreeWidget.name就是这么做的。
解决方案是使用模式同义词。

{-# Language PatternSynonyms #-}

module View.TreeWidget (pattern Name) where

pattern Name :: String
pattern Name = "tree_list_name"

现在你可以使用Name作为表达式和模式。

import qualified View.TreeWidget as TreeWidget

bla :: String -> Bool
bla TreeWidget.Name = True
bla "sdfsd"         = False
bla _               = True
jdzmm42g

jdzmm42g2#

正如Iceland_jack所解释的,你不能使用像name这样的值作为模式。你可以使用的模式本质上是 * 构造函数和文字 *,其中构造函数通常是出现在data声明中的大写形式,比如Maybe类型中的JustNothingPatternSynonyms扩展允许为已经声明的类型定义自定义构造函数。
然而,尽管我通常更喜欢模式而不是相等性检查,但在这种情况下,只检查someString == TreeWidget.name是否相等并采取相应的措施似乎更有意义。这可以通过guards很容易地完成:

bla someString
 | someString==TreeWidget.name  = True
bla "sdfsd" = False
bla _ = True

当然,由于结果也是一个布尔值,因此您也可以只使用逻辑运算符:

bla someString = someString==TreeWidget.name || someString/="sdfsd"

如果你喜欢无点,也可以写成

bla = or . ([(==TreeWidget.name), (/="sdfsd")]<*>) . pure

...但更有效的方法是为someString使用较短的名称。

相关问题