конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
нет, типы на ходу не меняются неявно
LazyByteString и StrictByteString это структурно разные типы
ну может тогда простое решение, это впихнуть в этот параметр явную конвертацию при вызове функции
Грубо говоря type LazyByteString= [StrictByteString]
да, так можно, но в данном случае, скорее всего, лучше просто одним типом пользоваться везде
как если кондуит возращает ByteString а TagSoup хочет String c этим и вожусь
вот например или я чего то не понимаю parseTree :: StringLike str => str -> [TagTree str] Build a TagTree from a string.
здесь нет явного указания на тип String
здесь str — типовая переменная, она может принимать значение любого типа, удовлетворяющего условию
а StringLike => надо же быть инстансем
именно. посмотри, какие типы принадлежат этому классу
Там есть инстансы для моих типов, но что то не то, этого я пока и не могу понять
OverloadedStrings уже включил, как советовали несколько раз?
какая ошибка после этого?
app/Main.hs:97:74: error: [GHC-83865] • Couldn't match type ‘B.ByteString’ with ‘[Char]’ Expected: String Actual: B.ByteString • In the second argument of ‘($)’, namely ‘L.toStrict resp’ In the second argument of ‘($)’, namely ‘fromString $ L.toStrict resp’ In the second argument of ‘($)’, namely ‘parseTree $ fromString $ L.toStrict resp’ | 97 | let tags = flattenTree $ universeTree $ parseTree $ fromString $ L.toStrict resp код в котором она spjPapers :: IO String spjPapers = do resp <- getHtml testUrl let tags = flattenTree $ universeTree $ parseTree $ fromString $ L.toStrict resp let links = map f $ sections (~== "<A>") $ takeWhile (~/= "<a name=haskell>") $ drop 5 $ dropWhile (~/= "<a name=current>") tags pure $ unlines links where f :: [Tag String] -> String f = dequote . unwords . words . fromTagText . head . filter isTagText dequote ('\"':xs) | last xs == '\"' = init xs dequote x = x вот так и происходит версия, что нужны тейквайл из байтстринга - не прошла, тоже ошибки, да и по ним понятно что дропы работают с листом Тегов
при этом есть такое Instances StringLike String StringLike ByteString StringLike ByteString StringLike Text StringLike Text
ну вот ты выход toStrict подаёшь на вход fromString. а какие типы на самом деле на выходе из toStrict и на входе fromString?
fromString :: IsString a => String -> a toStrict :: LazyByteString -> StrictByteString Есть еще конечно toString но мне кажеться это уж совсем перебор
да, тут уже перебор
ты пытаешься из зайца сделать белку, а потом из медведя сделать волка. а смысл где?
да просто считал что ByteString инстансе IsString
Реально я хочу строку пришедшую из кондуита (getResponseBody ) отдать TagSoupe - но пока упираюсь в типы, я понимаю, что что то не понимаю, но пока не понимаю, что, версия только что надо применить что то типа decodeUtf8
это не связано с твоим кодом
просто передавай бе конвертации
Response откуда берёшь? httpLbs?
дв - вот код getHtml :: Url -> IO HtmlByte getHtml url = let request = buildRequest domainBS pathBS (domainBs, pathBS) = urlFor url in do resp <- httpLBS request let status = getResponseStatusCode resp if status == 200 then do let body = getResponseBody resp pure body else do pure ""
получается что у тебя есть LBS, и parseTree принимает LBS. зачем конвертировать?
или надо как то это использовать httpSource
parseTree принимает, но потом c tags конфликт типов
ок, разобрались. давай следующую ошибку
вот тогда код такой spjPapers :: IO String spjPapers = do resp <- getHtml testUrl let tags = flattenTree $ universeTree $ parseTree resp let links = map f $ sections (~== "<A>") $ takeWhile (~/= "<a name=haskell>") $ drop 5 $ dropWhile (~/= "<a name=current>") tags pure $ unlines links where f :: [Tag String] -> String f = dequote . unwords . words . fromTagText . head . filter isTagText dequote ('\"':xs) | last xs == '\"' = init xs dequote x = x Ошибка опять в типах но уже относительно tags app/Main.hs:100:65: error: [GHC-83865] • Couldn't match type ‘L.ByteString’ with ‘[Char]’ Expected: [Tag String] Actual: [Tag HtmlByte] • In the second argument of ‘dropWhile’, namely ‘tags’ In the second argument of ‘($)’, namely ‘dropWhile (~/= "<a name=current>") tags’ In the second argument of ‘($)’, namely ‘drop 5 $ dropWhile (~/= "<a name=current>") tags’ | 100 | drop 5 $ dropWhile (~/= "<a name=current>") tags
откуда берётся HtmlByte?
HtmlByte это алиас его местный
перепиши код так, чтобы он работал только с LBS, без смешивания со String. в частности, сигнатура f мешает
На type HtmlByte = L.ByteString
но строка — это не один байт
наверно, ты хотел написать HtmlBytes
Это да орфография
вот вопрос такое работает [x | x@(TagBranch "a" _ _) <- universeTree tree] а нужно добавить условие на атрибуты, и я туплю, как это сделать например нужно, чтоб в выдаваемом теге был aria-label="More results", но не соображаю как проверить, или это нельзя просто сделать ?
> [x | x <- [1..10], x `mod` 2 == 0] [2,4,6,8,10]
гм, ты же 2 недели назад уже решил эту задачу
Да так все работает, вопрос про x@(TagBranch "a" _ _ )
https://t.me/haskell_learn/117810
Да даже нашел код, но уже сам внем путаюсь.... Так что буду думать как решить, чтоб было понятно хотябы мне )))
да и решил ее криво, результаты парсил, самостоятельно, это не то что хотелось
ну решил же! это круто! теперь, когда есть решение, можно его улучшать, оптимизировать а как хотелось?
ну сейчас, я вполне выдергиваю теги с линками и тег на следующий такт, думаю как лучше дернуть из тагбранчей hrefы
хотелось примерно то что сейчас получается, еще не очень красиво, но хоть понятно nextAttr = [(TE.encodeUtf8 "aria-label", TE.encodeUtf8 "Ещё результаты" )] linkAttr = [(TE.encodeUtf8 "jsname", TE.encodeUtf8 "UWckNb" )] --spjPapers :: IO [String] spjPapers = do resp <- getHtml testUrl B.writeFile "test.thml" resp let tree = parseTree resp utree = universeTree tree next = [x | x@(TagBranch tagName attrs innerTag) <- utree , ((tagName == "a" ) && (arrIn nextAttr attrs))] links = [x | x@(TagBranch tagName attrs innerTag) <- utree , ((tagName == "a" ) && (arrIn linkAttr attrs))] pure $ (links, next)
universeTree + фильтруешь по тэгу "a" и атрибуту "href"
next = [x | x@(TagBranch tagName attrs innerTag) <- utree , ((tagName == "a" ) && (arrIn nextAttr attrs))] -- давай сразу перепишем красиво next = [ x | x@(TagBranch "a" attrs _) <- utree , arrIn nextAttr attrs ]
pure $ (links, next) -- pure (links, next)
тут была мысль сделать функцию с параметрами а не делать сразу конкретный список
вот такое, не лучшее, но работает arrIn :: Eq a => [a] -> [a] -> Bool arrIn xs [] = False arrIn [] ys = True arrIn (x:xs) ys = if x `elem` ys then arrIn xs ys else False
if a then b else False === a && b
если не лень, это была попытка проектирования сверху, результат мне не очень нравиться, так что если не лень коментировать вот что пока есть, меня больше интересует коментарий по подходу, по елементам, понял, по чуток привыкаю... на модули еще не разбивал, и пока туплю как лучше
отформатируй код с помощью fourmolu или ormolu
сейчас попробую заставить коде
лучше в консольке запустить, а украшательством vscode потом заняться
(SearchAtom search searchDomain tsnew) == SearchAtom search searchDomain tsnew с этим hlint помогает
if (y == x) then True else memb x ys === if y == x then True else memb x ys === y == x || memb x ys
вроде включил ормолоу
А как помогает ? и как его привязать
Да я видел, просто от куда то притащил. они странные и не нужные, но пока были.... Думал пригодятся, но нет
запусти в терминале hlint Main.hs и посмотри
mconcat [ts1, ts2] === ts1 <> ts2
такого типа коменты ? app/Main.hs:21:23-42: Suggestion: Redundant bracket Found: (map (process time)) <$> searchList Perhaps: map (process time) <$> searchList
не уверен, что реализовано Semigroup для TS
T.Text писать постоянно некрасиво, лучше import Data.Text qualified as Text import Data.Text (Text) и дальше везде просто тип Text и функции типа Text.length
ты же пользуешься mconcat из Semigroup
if _ then True else False -- это совсем смешно. не показывай такое людям
В репле можно так посмотреть: > :i Monoid type Monoid :: * -> Constraint class Semigroup a => Monoid a where ... То есть чтобы у вас определён моноид, должна быть определена полугруппа. Кроме того, можно было бы набрать :i TS и получить список инстансов.
arrIn -- плохое название. оно же не с массивами работает. подобная функция есть для других типов под названием isSubsetOf, и тут можно такое же имя использовать
nextAttr = [(TE.encodeUtf8 "aria-label", TE.encodeUtf8 "Ещё результаты")] вот тут было бы красиво написать nextAttr = [("aria-label", "Ещё результаты")] и это даже будет правильно работать со строкой "aria-label", потому что мы работаем с байтами, и для латиницы байты с символами совпадают. но для строки "Ещё результаты" будет ошибка, потому что мы работаем с байтами, а кириллица байты не описывает (или описывает неправильно). что делать? можно, например, перевести байты из сети в юникод пере парсингом. но мне вот больше нравится с байтами работать, а с кириллицею не работать, поэтому я бы запрашивал гугл в английской локали и оставлял байтами.
setof = nub
(pos + (length urlList)) === pos + length urlList
foldr (\(x, y) xs -> if x == "href" then y : xs else xs) [] attrs === map (\(x, y) -> y) $ filter (\(x, _) -> x == "href") attrs === [y | (x, y) <- attr, x == "href"] === [y | ("href", y) <- attr]
Ну TS мой тип, я ее не определял, возможно она как то наследовалась, но не проверял... Я это имел в виду, как сделать знаю
спасибо, поправлю
понял, но мне в целом будет нужен гугл и яндекс, и боюсь что с русским, как минимум посковые фразы
согласен, а как решается, сразу мапами ? или есть сет, но он мне не попадался
спасибо, так мыслить пока не научился
вот как по атрибуту, так чтоб не париться его содержанием не знаю как сделать
тогда я бы сразу в Text весь ответ сервера перегнал и его уже парсил
что решается? nub — это библиотечная функция, которую вы переизобрели
в библиотеке containers есть и Map, и Set
понял, попробую, это я ступил
ещё раз советую пройти курс Москвина, помогает видеть filter/map
попробуй сам сформулировать условие, а мы подскажем
например по href не трогая "a" как имя тега
ок, сформулируй это кодом
[x | x@(TagBranch _ attrs _), "href" in attrs]
в целом понял, спасибо
замечательно, только теперь надо эту функцию "in" расписать. ну и синтаксис не такой, но не суть
Обсуждают сегодня