을 테스트하고 나 자신에 비해 다음과 같은 방식으로 코드를 작성하고 이상 발견추출 Hspec 내가 "첫 번째 원칙에서 하스켈 프로그램"을 통해 갈거야
type IntToInt = Fun Int Int
type TypeIdentity = ConcreteFunctorType Int -> Bool
type TypeComposition = ConcreteFunctorType Int -> IntToInt -> IntToInt -> Bool
checkSomething :: IO()
checkSomething = hspec $ do
describe "Some functor" $ do
it "identity property" $ do
property $ (functorIdentity :: TypeIdentity)
it "composition property" $ do
property $ (functorComposition :: TypeComposition)
내가 이것을 추출 시도
하지만 내 수준에서 내가 할 수 없습니다입니다 Sapan 후 : 그것은 내가이
checkFunctor :: (Functor f) => String -> f a -> IO()
checkFunctor description f = hspec $ do
describe description $ do
it "identity property" $ do
property $ (functorIdentity :: f a -> TypeIdentity)
it "composition property" $ do
property $ (functorComposition :: f a -> TypeComposition)
편집과 같은 무언가를 달성하기 위해 좋아했을 것
를 작동하게하는 방법을 알아낼
type TypeIdentity = Bool
type TypeComposition = Fun Int Int -> Fun Int Int -> Bool
checkFunctor :: forall f a. (Functor f) => String -> f a -> IO()
checkFunctor description f = hspec $ do
describe description $ do
it "identity property" $ do
property $ (functorIdentity :: f a -> TypeIdentity)
it "composition property" $ do
property $ (functorCompose' :: f a -> TypeComposition)
을 다음과 같이 이아 (Oia)의 대답은 내가 시도했지만 나는 다음과 같은 오류가 발생합니다
FunctorCheck.hs:22:25: error:
• Couldn't match type ‘a’ with ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
checkFunctor :: forall (f :: * -> *) a.
Functor f =>
String -> f a -> IO()
at FunctorCheck.hs:16:26
Expected type: f a -> TypeComposition
Actual type: f Int -> Fun Int Int -> Fun Int Int -> Bool
나를 임의의 값과 기능을 생성하는 유형을 정의하는 것은 다음 매우 복잡하게된다.
checkFunctor의 유형을 다음과 같은 특정 유형에 바인딩 할 수있는 방법이 있습니까?
checkFuntor :: checkFunctor :: forall f Int. (Functor f) => String -> f a -> IO()
물론 내가 이것을 시도하고 나에게 구문 분석 오류를 준다, 나는 그것이 'forall'을 정확하게 사용하지 않는다고 가정한다.
예, 가능합니다. 'ScopedTypeVariables'를 사용하면됩니다. GHC 8의'TypeApplications'와'AllowAmbiguousTypes'를 사용하면 훨씬 더 멋지게 만들 수 있습니다. –
'forall'은 새로운 타입 * 변수 *를 소개하기 위해 사용됩니다. * 'Int'와 같은 구체적인 * 유형은 도입 할 필요가 없으며 * 유형 변수 * 대신 삽입하십시오. 당신의 예제는 다음과 같다 :'checkFunctor :: forall f. (Functor f) => 문자열 -> f Int -> IO()'. 'checkFunctor'의 본문에는 그에 따라 필요한 것이 있습니다 :'functorIdentity :: f Int -> TypeIdentity'. – sapanoia