Нет экземпляра для (Показать a0), возникающего в результате использования 'shouldBe'

Я новичок в haskell и одновременно пытаюсь изучить hspec.

module ExercisesSpec where

import Test.Hspec
import Test.QuickCheck
import Control.Exception (evaluate)


halve :: [a] -> ([a], [a])
halve xs = splitAt (length xs `div` 2) xs

main :: IO ()
main = hspec $ do
  describe "halve" $ do
    it "0 elements" $ do
      halve [] `shouldBe` ([],[])

    it "1 element" $ do
      halve [1] `shouldBe` ([],[1])

    it "2 elements" $ do
      halve [1,2] `shouldBe` ([1],[2])

    it "3 elements" $ do
      halve [1,2,3] `shouldBe` ([1],[2,3])

    it "4 elements" $ do
      halve [1,2,3,4] `shouldBe` ([1,2],[3,4])

Хотя остальные тесты пройдены, проверка на 0 элементов не пройдена.

No instance for (Show a0) arising from a use of ‘shouldBe’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
  instance Show Double -- Defined in ‘GHC.Float’
  instance Show Float -- Defined in ‘GHC.Float’
  instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
    -- Defined in ‘GHC.Real’
  ...plus 38 others
In a stmt of a 'do' block: halve [] `shouldBe` ([], [])
In the second argument of ‘($)’, namely
  ‘do { halve [] `shouldBe` ([], []) }’
In a stmt of a 'do' block:
  it "0 elements" $ do { halve [] `shouldBe` ([], []) }

Когда я пытаюсь это сделать в ghci, все работает нормально.

*Exercises> halve []
([],[])

Кто-нибудь может мне помочь?

1 ответ

Ах, чтобы ответить на мой собственный вопрос, я вижу, что мне нужно сделать тип более конкретным. Это работает, если я добавлю halve :: [Int] -> ([Int], [Int]) выше моей функции.

Чтобы процитировать хорошие ответы, я прочитал в аудитории моего класса:

pbl64k

В общем, экземпляра Show для списков не существует. А как насчет списков функций? REPL выводит конкретный тип, который имеет экземпляр Show. Но не ожидайте, что [a] вообще будет один - если вы не сделаете его самостоятельно.

treeowl

pbl64k - это правильно и неправильно. Существует экземпляр Show для [a], если есть экземпляр Show для a. Это автоматически выводится. Проблема в том, что Хаскелл не знает, какой это экземпляр. [] может выглядеть как одно значение (и в машинном коде это, вероятно, так), но на уровне Haskell это полиморфный конструктор. Он может принимать любой тип списка, поэтому вам нужно что-то сказать, какой тип списка вы имеете в виду.

Другие вопросы по тегам