英文:
How do I modify the values of a tuple and then return them as a tuple of a tuple?
问题
I'm relatively new to programming and Haskell in general. I'm working my way through a book on the language and one of the exercises asks for the following:
Fill in the definition of the following function, using fst
and snd
:
f :: (a, b) -> (c, d) -> ((b, d), (a, c))
f = undefined
I'm confused what this function signature means for how the actual function should be defined, and for the order of operations in that definition. In plain language, is this saying "take a tuple, and another tuple, and then output the final mixed tuple"? Or is it saying "take a tuple, modify that tuple, and then mix that modified one with the original"?
My issue is, how do I compose the function definition so that fst
and snd
can make the new tuple? I know I shouldn't use a lot of brackets, but in my head I want to approach the problem by just making a single-line function with brackets to simply demarcate the order of operations, like:
f x y = (,) ((,) snd x snd y) ((,) fst x fst y)
But the compiler returns an error. Am I wildly overcomplicating this? x
and y
are bound to (a, b)
and (c, d)
respectively, so shouldn't I be able to access them and return a new tuple of a tuple with the order of operations I've made with my brackets?
英文:
I'm relatively new to programming and Haskell in general. I'm working my way through a book on the language and one of the exercises asks for the following:
Fill in the definition of the following function, using fst
and snd
:
f :: (a, b) -> (c, d) -> ((b, d), (a, c))
f = undefined
I'm confused what this function signature means for how the actual function should be defined, and for the order of operations in that definition. In plain language, is this saying "take a tuple, and another tuple, and then output the final mixed tuple"? Or is it saying "take a tuple, modify that tuple, and then mix that modified one with the original"?
My issue is, how do I compose the function definition so that fst
and snd
can make the new tuple? I know I shouldn't use a lot of brackets, but in my head I want to approach the problem by just making a single line function with brackets to simply demarcate the order of operations, like:
f x y = (,) ((,) snd x snd y) ((,) fst x fst y)
But the compiler returns an error. Am I wildly overcomplicating this? x
and y
are bound to (a,b)
and (c,d)
respectively, so shouldn't I be able to access them and return a new tuple of a tuple with the order of operations I've made with my brackets?
答案1
得分: 8
我是不是过于复杂化了这个?
很可能是,最直接的方式可能只是简单地进行模式匹配,如:
f :: (a, b) -> (c, d) -> ((b, d), (a, c))
f (a, b) (c, d) = ((b, d), (a, c))
虽然这不是一个“巧妙的技巧”或其他什么,但它可读性强,易于检查、调试和修复。
至于实现,你可以修复如下:
f x y = (,) ((,) (snd x) (snd y)) ((,) (fst x) (fst y))
或者更方便地使用:
f x y = ((snd x, snd y), (fst x, fst y))
但是,如果定义模式意味着你要引入 lambda 表达式,使用 fst
和 snd
通常很有用。如果你可以定义一个模式,通过使用元组模式,可以使代码更可读。
对于你的函数,顺便说一句,实际上只有一种合理的实现方式(除了在(子)表达式中使用 undefined
之外),Djinn 是一个可以(穷举地)列举简单类型实现的工具,而这是 Djinn 能找到的唯一一种。
英文:
> Am I wildly overcomplicating this?
Probably yes, the most straightforward way is probably to simply do pattern matching, like:
f :: (a, b) -> (c, d) -> ((b, d), (a, c))
f (a, b) (c, d) = ((b, d), (a, c))
while it is not a "clever trick" or something, it is readable, and easy to inspect, debug and fix.
As for the implementation, you can fix this with:
f x y = (,) ((,) (snd x) (snd y)) ((,) (fst x) (fst y))
or make this more convenient with:
f x y = ((snd x, snd y), (fst x, fst y))
but using fst
and snd
is typically useful if defining patterns would mean you introduce a lambda expression for example. If you can define a pattern, by using a tuple pattern you make this more readable.
For your function, there is by the way only one sensical implementation (other than using undefined
somewhere as (sub)expression), Djinn is a tool that can (exhaustively) enumerate implementations for simply types, and this is the only one that Djinn can find.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论