使用非基本类型解决类型歧义

时间:2018-06-03 19:51:38

标签: regex haskell types web-scraping

我很难在下面的代码中找出解决这种类型歧义的方法。我试图使用库Text.HTML.Scalpel来获取具有满足正则表达式的href属性的所有元素。

{-# LANGUAGE OverloadedStrings #-}

import           Control.Monad
import qualified Data.ByteString.Char8  as B8
import           Data.List
import           Network.HTTP.Simple
import           Text.HTML.Scalpel.Core
import           Text.Regex.Posix

main :: IO ()
main = do
  content <- fetchUrlBody "http://en.wikipedia.org/wiki/Lists_of_American_institutions_of_higher_education"
  print $ scrapeStringLike content getStateListings

fetchUrl :: Request -> IO (Response B8.ByteString)
fetchUrl req = httpBS req

fetchUrlBody :: Request -> IO (B8.ByteString)
fetchUrlBody req = fmap getResponseBody $ fetchUrl req

getStateListings :: Scraper B8.ByteString [B8.ByteString]
getStateListings =
  attrs "href" ("a" @: ["href" @=~ "[^/wiki/List_of_colleges_and_universities_in_]"])

给出以下错误:

     Ambiguous type variable re0 arising from a use of @=~
      prevents the constraint (RegexLike re0 String) from being solved.
      Probable fix: use a type annotation to specify what re0 should be.
      These potential instance exist:
        instance RegexLike Regex String
          -- Defined in Text.Regex.Posix.String
     In the expression:
        "href" @=~ "[^/wiki/List_of_colleges_and_universities_in_]"
      In the second argument of (@:), namely
        ["href" @=~ "[^/wiki/List_of_colleges_and_universities_in_]"]
      In the second argument of attrs, namely
        ("a"
            @: ["href" @=~ "[^/wiki/List_of_colleges_and_universities_in_]"])
   |
23 |   attrs "href" ("a" @: ["href" @=~ "[^/wiki/List_of_colleges_and_universities_in_]"])
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我尝试了各种各样的事情,包括改变麻烦的路线:

getStateListings :: Scraper B8.ByteString [B8.ByteString]
getStateListings =
  attrs "href" ("a" @: ["href" @=~ (makeRegex "[^/wiki/List_of_colleges_and_universities_in_]" :: Regex)])

这似乎在RegexLike约束中满足re0,但现在它也需要源类型。我不知道如何指定类型注释,使正则表达式为RegexLike Regex ByteString类型。新错误是:

     Ambiguous type variable source0 arising from a use of makeRegex
      prevents the constraint (RegexMaker
                                  Regex CompOption ExecOption source0) from being solved.
      Probable fix: use a type annotation to specify what source0 should be.
      These potential instances exist:
        instance RegexMaker Regex CompOption ExecOption B8.ByteString
          -- Defined in Text.Regex.Posix.ByteString
        instance RegexMaker Regex CompOption ExecOption String
          -- Defined in Text.Regex.Posix.String
        ...plus two instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
     In the second argument of (@=~), namely
        (makeRegex "[^/wiki/List_of_colleges_and_universities_in_]" ::
            Regex)
      In the expression:
        "href"
          @=~
            (makeRegex "[^/wiki/List_of_colleges_and_universities_in_]" ::
               Regex)
      In the second argument of (@:), namely
        ["href"
            @=~
              (makeRegex "[^/wiki/List_of_colleges_and_universities_in_]" ::
                 Regex)]
   |
23 |   attrs "href" ("a" @: ["href" @=~ (makeRegex "[^/wiki/List_of_colleges_and_universities_in_]" :: Regex)])
   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 个答案:

答案 0 :(得分:3)

咒语应该是

public class ListClickHandlerDelete implements AdapterView.OnItemLongClickListener
{
    @Override
    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) 
    {
        String listPosition = list.get(position);
        return true;
    }
}

"href" @=~ (makeRegex ("^/wiki/List_of_colleges_and_universities_in_" :: String) :: Regex) 在其参数类型中是多态的,因此您需要@=~来确定它。没有:: Regex,因此您需要使用IsString RegexmakeRegex极具多态性。它的返回类型已经使用makeRegex确定,因此您需要为其参数:: Regex提供过去:: String的多态性。

你可以用

来清理这个烂摊子
-XOverloadedStrings