2010-07-14 9 views
4

그것은 일반적으로 다음과 같은 불법 보인다하스켈 클래스 정의의 암시 적 타입 매개 변수?

의미가
class Foo a where 
    foo :: a -> b -> a 

; b는 무엇을 알 수 있습니까? 우리가은 Functor의 정의를 보면

그러나 :

class Functor f where 
    fmap :: (a -> b) -> f a -> f b 

우리는 ab 우리가 단지 형 변수로 f을 지정하더라도 게재를 참조하십시오. 컴파일러에서 예를 들어 볼 수 있기 때문에 이것이 허용 된 것 같습니다. f a이고 f 그 자체가 a이어야한다는 것을 알 수 있으므로 Functor 정의의 다른 곳에서 a을 사용하는 것이 안전합니다. 나 맞아?

답변

6

각 행을 별도로 살펴 보겠습니다.

class Functor f where 

Functor라는 단일 매개 변수 유형 클래스를 선언; 이를 만족시키는 형식은 f이라고합니다. 어떤 함수 정의처럼

fmap :: (a -> b) -> f a -> f b 

은 모든 프리 타입 변수는 암시이다 forall ED - 그들은 무엇으로 대체 할 수있다. 그러나 첫 줄 덕분에 f이 범위에 포함됩니다. 따라서 fmap의 유형은 fmap :: forall a b. Functor f => (a -> b) -> f a -> f b입니다. 즉, 모든 펑은 종류 (유형의 유형) * -> *이 있어야합니다 어떤 abf 위해 일할 수 fmap의 정의를 가질 필요가; 즉, 다른 유형 인 [] 또는 Maybe 또는 IO과 같은 유형이어야합니다.

당신이 말한 바가 잘못되었습니다. a은 특별하지 않으며 Functor에 다른 기능이있는 경우 동일한 a 또는 b이 표시되지 않습니다. 그러나 컴파일러 일 경우 f의 종류가 무엇인지 알아 내기 위해 f a 비트를 사용합니다. 또한 Foo 클래스는 완전히 합법적입니다. 어떤b에 대한

instance Foo (a -> b) where 
    foo f _ = f 

이 만족을 foo :: a -> b -> a 다음과 같이 나는 인스턴스를 지정할 수 있습니다; Foo (a -> b)b이 다릅니다. 틀림없이 아주 흥미로운 사례는 아니지만 완벽하게 합법적입니다.

3

"알 필요"가 없습니다. 유형 검사 만하면됩니다 (즉, 유형 검사를하지 않아도됩니다). b은 무엇이든 될 수 있습니다. foo 함수는 두 번째 매개 변수로 모든 유형을 사용할 수 있어야합니다.

는 서곡에서 const 기능을 고려

const   :: a -> b -> a 
const x _  = x 

어떻게 무엇 b "알고있다"않습니다 (또는 a를, 그 문제에 대한)입니까?