Tôi có một ví dụ về hàm, trong đó tôi không thể viết một loại trong mệnh đề where
. replace
là một hàm, thay thế tất cả X bằng Y trong một danh sách đã cho.Haskell: Khai báo kiểu trong `where`
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y xs = map helper xs
where
helper :: (Eq a) => a -> a
helper = (\el -> if el == x then y else el)
Khi tôi cố gắng biên dịch chức năng này, tôi nhận được một lỗi:
ProblemsArithmetics.hs:156:31:
Could not deduce (a ~ a1)
from the context (Eq a)
bound by the type signature for
replace :: Eq a => a -> a -> [a] -> [a]
at ProblemsArithmetics.hs:152:12-41
or from (Eq a1)
bound by the type signature for helper :: Eq a1 => a1 -> a1
at ProblemsArithmetics.hs:155:15-30
‘a’ is a rigid type variable bound by
the type signature for replace :: Eq a => a -> a -> [a] -> [a]
at ProblemsArithmetics.hs:152:12
‘a1’ is a rigid type variable bound by
the type signature for helper :: Eq a1 => a1 -> a1
at ProblemsArithmetics.hs:155:15
Relevant bindings include
el :: a1 (bound at ProblemsArithmetics.hs:156:16)
helper :: a1 -> a1 (bound at ProblemsArithmetics.hs:156:5)
xs :: [a] (bound at ProblemsArithmetics.hs:153:13)
y :: a (bound at ProblemsArithmetics.hs:153:11)
x :: a (bound at ProblemsArithmetics.hs:153:9)
replace :: a -> a -> [a] -> [a]
(bound at ProblemsArithmetics.hs:153:1)
In the second argument of ‘(==)’, namely ‘x’
In the expression: el == x
Cùng lúc đó, nếu tôi bỏ qua
helper :: (Eq a) => a -> a
mã được biên dịch tốt.
Trong khi tôi hiểu được logic đằng sau nó (a
trong replace
khai báo kiểu và a
trong helper
khai báo kiểu khác nhau a
s), và có ít nhất 2 cách giải quyết (bỏ qua khai báo kiểu hay vượt qua x
và y
như tham số cho helper
chức năng), câu hỏi của tôi là:
Có cách nào để báo cho trình biên dịch biết rằng tôi có cùng loại trong cả hai loại khai báo không?
Có: https://wiki.haskell.org/Scoped_type_variables – Jubobs
Thử thêm '{- # LANGUAGE ScopedTypeVariables # -}'. Tôi không thể kiểm tra bây giờ, bất cứ ai được tự do để biến bình luận của tôi thành một câu trả lời. – Franky