Тестирование лени функции IsString s => s -> Bool - PullRequest
0 голосов
/ 14 декабря 2018

Можно ли как-нибудь проверить, что функция p :: IsString s => s -> Bool лениво оценивает свой ввод?Таким образом, он только потребляет часть своего ввода при определении своего результата.И возможно ли так, чтобы он был совместим как с String, так и с Data.Text.Lazy?

Я смотрел на модульное тестирование Q & A для неопределенного, оцененного в ленивом выражении в Haskell , который конкретно не распространяется на IsString, и я нашел пакет StrictCheck на Hackage, в котором я не совсем уверен, как работает.Это применимо здесь?

Проблема

У меня есть предикат,

p :: IsString s => s -> Bool

и тест Hspec,

{-# LANGUAGE OverloadedStrings #-}

...
import Data.String (fromString)

spec_p :: Spec
spec_p =
  describe "p" $
    it "is lazy" $ p (fromString x) `shouldBe` y
      where
        x = "foo" ++ [undefined]
        y = True

, который не проходитесли p ("foo" ++ [undefined]) пытается потреблять больше, чем "foo".

Это прекрасно работает для моей String реализации,

import qualified Data.List as L

p :: String -> Bool
p = ("foo" `L.isPrefixOf`)

Но это не так хорошо работает на моем Data.Text.Lazy реализация,

{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text.Lazy as T
import           Data.Text.Lazy (Text)

p :: Text -> Bool
p = ("foo" `T.isPrefixOf`)

, поскольку fromString не преобразует ленивый String в ленивый Text способом, который сохраняет undefined без оценки.Я могу проверить, что ленивая версия работает, написав специализированный тест,

pTest :: Bool
pTest = p (T.fromChunks [ "foo", undefined ]) -- True

, но я не могу контролировать, как fromString кусков.


Попытка решения:

Я пытался написать свою собственную обертку для управления разбивкой на fromString,

import qualified Data.Text      as T
import qualified Data.Text.Lazy as LT

newtype LazyChunkyText = LazyChunkyText LT.Text deriving (Show)
instance IsString LazyChunkyText where
  fromString = LazyChunkyText . LT.fromChunks . map (T.pack . return)

Но поскольку fromChunks занимает [T.Text], мне нужно T.pack.

Значение моего [undefined] оценивается.

...