문제

Stackoverflow에서 찾은 조언을 바탕으로 Haskell을 파고 들고 있습니다. Haskell의 매개 변수화 된 유형이 C# 제네릭과 매우 흡사하다는 것을 알게되어 기뻤습니다. 두 언어 모두 유형 매개 변수 (일반적으로)에 대한 단일 문자를 조언하고 두 언어는 유형 매개 변수의 실제 유형을 대체하기위한 비슷한 프로세스를 따르는 것으로 보입니다. 나는 그로 인해 개념을 아주 빨리 집행했다.

이것으로 이어지는 것은 다음과 같습니다. Haskell의 매개 변수화 유형이 C# 일반 유형과 다른 몇 가지 방법은 무엇입니까? 루비를 배우면서 한 언어에서 익숙한 개념이 새로운 언어에서 동일하다고 생각하는 데 큰 어려움을 겪을 수 있다는 것을 알고 있습니다. 일반적으로 기능이 실제로 ~이다 매우 비슷합니다 ... 보통 ~ 아니다 100% 동일합니다. 그렇다면 C# 제네릭에 대한 지식을 기반으로 매개 변수화 된 유형을 이해한다고 가정하면 물린 "Gotchas"중 일부는 무엇입니까?

감사.

도움이 되었습니까?

해결책

명심해야 할 차이점은 다음과 같습니다.

C#은 하위 유형이 있지만 Haskell은 그렇지 않습니다. 알다 단순히 Haskell 유형을 보면 더 많은 것들.

id :: a -> a

이 haskell 함수는 유형의 값을 취하고 동일한 유형의 동일한 값을 반환합니다. 당신이 그것을 주면 Bool, 반환합니다 Bool. 줘 Int, 반환합니다 Int. 줘 Person, 반환합니다 Person.

C#에서는 확실 할 수 없습니다. 이것은 C#의 '기능'입니다.

public T Id<T>(T x);

이제 하위 유형으로 인해 그렇게 부를 수 있습니다.

var pers = Id<Person>(new Student());

하는 동안 pers 유형입니다 Person,에 대한 논쟁 Id 기능은 아닙니다. 사실로 pers 단순한 유형보다 더 구체적인 유형을 가질 수 있습니다 Person. Person 그것을 보장하는 추상 유형 일 수도 있습니다 pers 보다 구체적인 유형이 있습니다.

보시다시피, 단순한 기능을 사용하더라도 id .NET 유형 시스템은 이미 더 엄격한 유형 시스템보다 훨씬 많은 것을 허용합니다. Haskell. 일부 프로그래밍 작업을 수행하는 데 유용 할 수도 있지만, 단지 유형의 물건 (Haskell에서 할 수있는 기쁨)을 찾아 프로그램에 대해 추론하기가 더 어려워집니다.


그리고 두 번째는 있습니다 애드 혹 '유형 클래스'로 알려진 메커니즘을 통해 Haskell의 다형성 (일명 과부하).

equals :: Eq a => a -> a -> Bool

이 함수는 두 값이 동일했는지 확인합니다. 그러나 두 값뿐만 아니라 인스턴스가있는 값 만 Eq 수업. 이것은 C#의 유형 매개 변수에 대한 제약과 유사합니다.

public bool Equals<T>(T x, T y) where T : IComparable

그러나 차이가 있습니다. 우선, 하위 유형 : 당신은 그것을 인스턴스화 할 수 있습니다. Person 그리고 그것을 가지고 전화하십시오 Student 그리고 Teacher.

그러나 이것이 컴파일하는 것도 차이가 있습니다. C# 코드는 거의 정확히 그 유형의 말에 따라 컴파일됩니다. 유형 검사기는 인수가 적절한 인터페이스를 구현하고 양호보다 우수합니다.

Haskell 코드는 다음과 같은 것을 준수합니다.

equals :: EqDict -> a -> a -> Bool

함수는 an을 얻습니다 추가 논쟁, 모든 기능의 사전은 Eq 것들. 이 기능을 사용할 수있는 방법과 다음과 함께 컴파일하는 내용은 다음과 같습니다.

b1 = equals 2 4          --> b1 = equals intEqFunctions 2 4
b2 = equals True False   --> b2 = equals boolEqFunctions True False

이것은 또한 하위 유형이 그러한 고통을 만드는 것을 보여줍니다. 가능하면 상상해보십시오.

b3 = equals someStudent someTeacher
     --> b3 = equals personEqFunctions someStudent someTeacher

어떻게 지내세요 personEqFunctions 사전 a Student a와 같습니다 Teacher? 그들은 같은 필드도 가지고 있지 않습니다.

요컨대, 첫눈에 Haskell 유형 제약 조건은 .NET 유형 제약 조건처럼 보일 수 있지만 완전히 다르게 구현되어 실제로 두 가지 다른 것들로 컴파일됩니다.

다른 팁

우리는 지금 Haskell 형 수업으로 다른 일을 할 수 있습니다. Haskell의 "Generics"에 대한 인터넷 검색은 대부분의 사람들이 "제네릭"이라고 생각하는 표준 파라 메트릭 다형성을 넘어서는 고위 다형성 제네릭 프로그래밍의 전체 분야를 열어줍니다.

예를 들어, GHC는 최근에 유형 패밀리를 얻었으므로 모든 종류의 흥미로운 유형 프로그래밍 기능이 가능합니다. 매우 간단한 예는 임의의 다형성 용기에 대한 유형 당 데이터 표현 결정입니다.

나는 말하기, 목록, 수업을 만들 수 있습니다.

class Listy a where

    data List a 
             -- this allows me to write a specific representation type for every particular 'a' I might store!

    empty   :: List a
    cons    :: a -> List a -> List a
    head    :: List a -> a
    tail    :: List a -> List a

목록을 인스턴스화하는 모든 것에서 작동하는 기능을 작성할 수 있습니다.

map :: (Listy a, Listy b) => (a -> b) -> List a -> List b
map f as = go as
  where
    go xs
        | null xs   = empty
        | otherwise = f (head xs) `cons` go (tail xs)

그러나 우리는 특정한 표현 유형을 제공 한 적이 없습니다.

이제는 일반 목록의 클래스입니다. 요소 유형을 기반으로 특정 교활한 표현을 줄 수 있습니다. 예를 들어 INT 목록은 배열을 사용할 수 있습니다.

instance Listy Int where

data List Int = UArray Int Int

...

따라서 매우 강력한 일반 프로그래밍을 시작할 수 있습니다.

또 다른 큰 차이점은 C# 제네릭이 유형 생성자 (예 : *이외의 다른 종류)보다 추상화를 허용하지 않는다는 것입니다. 다음 데이터 유형을 C# 클래스로 번역하십시오.

newtype Fix f = In { out :: f (Fix f) }

"한 언어에서 친숙한 개념이 다른 언어 (새로운]에 대해 동일하다고 생각하는 데 큰 어려움을 겪을 수 있습니다.

Haskell 유형 클래스를 사용할 때 이해해야하는 주요 차이점 (예 : Ruby)은 다음과 같습니다. 다음과 같은 기능이 주어졌습니다

add :: Num a => a -> a -> a
add x y = x + y

이것은 그렇습니다 ~ 아니다 의미 x 그리고 y 둘 다 모든 유형의 클래스입니다 Num. 그것은 의미합니다 x 그리고 y 정확히 같은 유형이며 어떤 유형이 클래스입니다. Num. "물론 당신은 말합니다. 같은 것입니다 . "나도 말하지만 x an Int 그리고 y an Integer, 그것은 a를 추가하는 것과 같습니다 Fixnum 그리고 Bignum 루비에서. 꽤:

*Main> add (2::Int) (3::Integer)

<interactive>:1:14:
    Couldn't match expected type `Int' against inferred type `Integer'
    In the second argument of `add', namely `(3 :: Integer)'
    In the expression: add (2 :: Int) (3 :: Integer)
    In the definition of `it': it = add (2 :: Int) (3 :: Integer)

다시 말해, 서브 클래싱 (둘 다 Num 인스턴스는 물론 인스턴스입니다 Eq)) 그리고 오리 타이핑은 사라졌습니다.

이것은 매우 간단하고 분명하게 들리지만 적어도 수년간의 Java와 Ruby에서 온다면 지적 적으로보다 본능적으로 이해하기 위해 자신을 훈련시키는 데 꽤 시간이 걸립니다.

그리고 아니요, 일단 내가 이것의 교수형을 얻었을 때, 나는 서브 클래스를 조금 놓치지 않습니다. (글쎄, 아마도 조금이라도 조금 더 많이 잃어버린 것보다 훨씬 더 많이 얻었습니다. 그리고 정말로 그것을 놓칠 때, 나는 실존 유형을 오용하려고 노력할 수 있습니다.)

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