2014-04-28 3 views
0

나는 일련의 조리법과 원하는 출력을 통해 필요한 중간 제품의 수를 알 수 있습니다.사용하지 않은 매개 변수 유형을 추론 할 수 없습니다 - 매개 변수를 사용하면 사라집니다.

data Recipe = Recipe { name :: String 
        , ingredients :: [(Recipe, Int)] 
        } deriving (Eq) 

instance Show Recipe where 
     show Recipe{name=n} = show n 

foldRecipes :: (Integral a) => [(Recipe, a)] -> (Recipe, a) -> [(Recipe, a)] 
foldRecipes acc [email protected](Recipe{ingredients=i}, n) = 
     acC++ requirements [(recipe, fromIntegral count * n) | (recipe, count) <- i] 

requirements :: (Integral a) => [(Recipe, a)] -> [(Recipe, a)] 
requirements m = 
     foldl foldRecipes m m 

main = 
     let dough = Recipe{ name = "dough", ingredients = [(flour, 200), (water, 200)] } 
      flour = Recipe{ name = "flour", ingredients = [] } 
      water = Recipe{ name = "water", ingredients = [] } 

     in putStrLn $ show $ requirements [(dough, 2)] 

출력 : [("dough",2),("flour",400),("water",400)이 제작에가는 길에

, 나는 다음과 같은 버전이 작동하지 않는다는 사실에 달렸다 누군가 이유를 설명 할 수? 형식 서명에 Integral a 대신 명시적인 Int을 사용하면 작동합니다.

foldRecipes :: (Integral a) => [(Recipe, a)] -> (Recipe, a) -> [(Recipe, a)] 
foldRecipes acc [email protected](Recipe{ingredients=i}, _) = 
     acC++ requirements i 

출력 : 함수는 일반 정수형 Integral a를 사용하여 목록을 받아들이는 반면 ingredients 항상 유형 [(Recipe, Int)]의 목록이 포함되어 있기 때문에

test_unused.hs:10:30: 
    Could not deduce (a ~ Int) 
    from the context (Integral a) 
     bound by the type signature for 
       foldRecipes :: Integral a => 
           [(Recipe, a)] -> (Recipe, a) -> [(Recipe, a)] 
     at test_unused.hs:8:16-76 
     `a' is a rigid type variable bound by 
      the type signature for 
      foldRecipes :: Integral a => 
          [(Recipe, a)] -> (Recipe, a) -> [(Recipe, a)] 
      at test_unused.hs:8:16 
    Expected type: [(Recipe, a)] 
     Actual type: [(Recipe, Int)] 
    In the first argument of `requirements', namely `i' 
    In the second argument of `(++)', namely `requirements i' 
    In the expression: acC++ requirements i 

답변

4
foldRecipes :: (Integral a) => [(Recipe, a)] -> (Recipe, a) -> [(Recipe, a)] 
foldRecipes acc [email protected](Recipe{ingredients=i}, _) = 
    acC++ requirements i 

은 위의 작동하지 않습니다. aInt은 다른 유형이므로 ++을 사용하여 다른 유형의 목록을 연결할 수 없습니다.

다른 버전의 함수는 Int을보다 일반적인 형식으로 변환하기 위해 fromIntegral을 사용하기 때문에 작동합니다.