내 haskell 코드를 원하는대로 모듈화 할 수 없습니다. 나는 아마도 객체 지향 패러다임에 갇혀 있고 기능적으로 생각하는 데 어려움을 겪고 있을지 모르지만 나는 완전히 곤두박질 친다.함수 정의를 여러 파일로 분할하여 모듈성이 향상됩니다.
conjunction :: TruthType -> TruthType -> TruthType
conjunction (TT_Percent x) (TT_Percent y) = TT_Percent (x*y)
conjunction (TT_Boolean "t") (TT_Boolean "t") = TT_Boolean "t"
conjunction (TT_Boolean "t") (TT_Boolean "f") = TT_Boolean "f"
conjunction (TT_Boolean "f") (TT_Boolean "t") = TT_Boolean "f"
conjunction (TT_Boolean "f") (TT_Boolean "f") = TT_Boolean "f"
disjunction :: TruthType -> TruthType -> TruthType
disjunction (TT_Percent x) (TT_Percent y) = TT_Percent (x + (1-x)*y)
disjunction (TT_Boolean "t") (TT_Boolean "t") = TT_Boolean "t"
disjunction (TT_Boolean "t") (TT_Boolean "f") = TT_Boolean "t"
disjunction (TT_Boolean "f") (TT_Boolean "t") = TT_Boolean "t"
disjunction (TT_Boolean "f") (TT_Boolean "f") = TT_Boolean "f"
이 컴파일 및 실행 :
data TruthType = TT_Boolean String
| TT_Percent Double
conjunction :: TruthType -> TruthType -> TruthType
disjunction :: TruthType -> TruthType -> TruthType
일반적으로, 당신은 다음과 같이 서로 옆에 이러한 기능을 구현하는 것이 :
나는 데이터와 그것을 작동 두 가지 기능을 가지고 정확히 내가 기대했던 것처럼. 문제는 약 20 개의 서로 다른 TruthTypes를 구현할 계획이며, 각각에 대해 더 많은 기능을 제공한다는 것입니다. 이 섹션 모두 같은 파일에있는 경우
-- TT_Percent
conjunction (TT_Percent x) (TT_Percent y) = TT_Percent (x*y)
disjunction (TT_Percent x) (TT_Percent y) = TT_Percent (x + (1-x)*y)
-- TT_Boolean
conjunction (TT_Boolean "t") (TT_Boolean "t") = TT_Boolean "t"
conjunction (TT_Boolean "t") (TT_Boolean "f") = TT_Boolean "f"
conjunction (TT_Boolean "f") (TT_Boolean "t") = TT_Boolean "f"
conjunction (TT_Boolean "f") (TT_Boolean "f") = TT_Boolean "f"
disjunction (TT_Boolean "t") (TT_Boolean "t") = TT_Boolean "t"
disjunction (TT_Boolean "t") (TT_Boolean "f") = TT_Boolean "t"
disjunction (TT_Boolean "f") (TT_Boolean "t") = TT_Boolean "t"
disjunction (TT_Boolean "f") (TT_Boolean "f") = TT_Boolean "f"
, 내가 컴파일 오류가 나는 함께 재정의하고 있어요 주장 얻을 : 그래서 그들이에 작용하는 TruthType 생성자를 기반으로 그룹 내 기능을 더 의미 분리 함수. 나는 오래된 정의를 지우고 싶지 않다. 두 정의가 모두 유효하기를 바란다. 이 재 정의를 허용하기 위해 사용할 수있는 컴파일러 플래그가 있습니까?
궁극적으로 제 목표는 각기 다른 진실 유형을 자체 파일에 정의하는 것입니다. 그렇게하면 어떤 함수를 사용해야할지 모르기 때문에 모호한 오류가 발생합니다. GHC가 실제로 TruthType에 대해 정의 된 하나만 정의되었으므로 GHC에서 모든 것을 시도 할 수있는 방법이 있습니까?
추신. 이것은 타입 클래스를위한 훌륭한 유스 케이스처럼 보일지도 모르지만 실제로는 그렇지 않습니다.
class (Show a, Eq a) => TruthClass a where
conjunction :: a -> a -> a
disjunction :: a -> a -> a
instance TruthClass Bool where
conjunction True True = True
conjunction True False = False
conjunction False True = False
conjunction False False = False
disjunction True True = True
disjunction True False = True
disjunction False True = True
disjunction False False = False
instance TruthClass Double where
conjunction x y = x*y
disjunction x y = x + (1-x)*y
classReturn :: (TruthClass a) => String -> a -- This fails to compile because it would allow the failure function below, which violates conjunction's type
classReturn "True" = True
classReturn "False" = False
classReturn "1" = 1
classReturn "0" = 0
failure = conjunction (classReturn "True") (classReturn "1")
이
편집 :
좋아, 내가 지금 잘 설명 할 수 나는 "인스턴스"TruthType의,이 예에서 "classReturn"기능 같은 것을 반환하는 함수를 쓸 수 있어야 왜 타입 클래스를 사용할 수 없으며, 왜 제안 된 솔루션이 나를 위해 작동하지 않는지. (아래 augustss의 솔루션을 기반으로) 다음에 봐 :
*Main> conjunction True True -- works because type is inferred
True
*Main> classReturn "True" :: Bool -- works because type is explicitly stated
True
*Main> classReturn "True" -- does not work, but this is what I need
<interactive>:1:0:
Ambiguous type variable `a' in the constraint:
`TruthClass a'
arising from a use of `classReturn' at <interactive>:1:0-17
Probable fix: add a type signature that fixes these type variable(s)
를 내 프로그램에서, 나는 그것이 유형을 지정할 수 없습니다. parsec을 사용하여 입력 파일을 구문 분석하고 있습니다. "#bool"행에 도달하면 이후에 생성되는 모든 변수는 TT_Boolean 유형이어야합니다. "#percent"에 도달하면 모든 후속 변수는 TT_Percent 유형이어야합니다. 따라서 함수를 호출 할 때 형식이 무엇인지 하드 코딩 할 수는 없으며 형식 클래스를 사용하는 경우 하드 코드해야합니다. 데이터를 사용하는 솔루션은이 문제를 해결하지만 데이터로 인해 모듈성이 부족합니다.
'classReturn'도 오버로드하지 않는 이유는 무엇입니까? 그냥 수업의 구성원이되도록하십시오. – augustss
BTW, 나는'x + y - x * y'가 대칭성을 더 잘 강조한다고 생각하지만 어쩌면 버전에 대한 숫자 적 이유가있을 수 있습니까? – augustss
귀하의 의견에 뭔가 빠졌습니다. – augustss