문제

Haskell의 범위에 문제가 있습니다 where 정의. 다음 기능이있을 때 f, 내가 전달하고 싶은 곳 x 로컬로 정의 된 함수에 f1 매개 변수로 설명하지 않고 x 출력의 하나와 호환되지 않습니다 f1, 동일하지만 :

f :: Eq a => a -> [a]
f x = f1 x
    where
        f1 :: Eq a => a -> [a]
        f1 y = [ x, y ]

오류는 다음과 같습니다.

    Couldn't match expected type `a1' against inferred type `a'
      `a1' is a rigid type variable bound by
           the type signature for `f1' at test.hs:4:11
      `a' is a rigid type variable bound by
          the type signature for `f' at test.hs:1:8
    In the expression: x
    In the expression: [x, y]
    In the definition of `f1': f1 y = [x, y]
Failed, modules loaded: none.

그러나 내가 통과 할 때 x 기능과 함께 다음 코드에서했던 것처럼 추가 매개 변수로 g, 그것은 잘 작동합니다 :

g :: Eq a => a -> [a]
g x = g1 x x
    where
        g1 :: Eq a => a -> a -> [a]
        g1 x y = [ x, y ]

유형을 만드는 방법이 있습니까? a 안에 f 유형과 호환됩니다 a (또는 a1) 안에 f1?

도움이 되었습니까?

해결책

코드의 문제는 로컬 스코핑 된 F1 유형 서명입니다. F1이 모든 유형을 취할 수 있음을 지정합니다

f1 :: Eq a => a -> [a]

이것은 로컬 기능이지만,이 함수는 F 내에 존재하지 않는 유형을 취할 수 있도록이 기능을 일반화했습니다.

F1 유형 서명을 제거하십시오.

편집 : 내 게시물을 나 자신에게 다시 읽으십시오. 조금 불분명합니다. F1의 A는 무엇이든 할 수있는 매개 변수화 유형이지만, 전달 된 인수는 이미 f에 묶여 있습니다. 따라서이 기능은 부모 기능이받는 것만받을 수 있으며, 그 규칙을 깨뜨리는 유형 서명입니다. 조금 더 분명하기를 바랍니다.

다른 팁

데이브가 바로 위에 있습니다. 그것을 생각하는 또 다른 방법은 두 유형 서명이 변수를 참조하더라도 a, 실제로는 같은 유형 변수가 아닙니다. Haskell-Prime 표기법에서 두 서명 모두보다 명시 적으로 작성 될 수 있습니다.

forall a . Eq a => a -> [a]

그것을 의미합니다 둘 다 함수는 어떤 유형의 인수를 받아 들일 수 있습니다 (EQ 내에서). 이것은 분명히 여기에 해당되지 않습니다. Standard Haskell 98에서 유일한 옵션은 유형 서명을 포기하는 것입니다. f1. 그러나 GHC (및 기타?) 지원 어휘 스코핑 유형 변수. 그래서 당신은 쓸 수 있습니다

{-# LANGUAGE ScopedTypeVariables #-}

f :: forall a. Eq a => a -> [a]
f x = f1 x
    where
        f1 :: a -> [a]
        f1 y = [ x, y ]

그리고 그것은 잘 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top