我有一个函数ip
,我无法改变:
ip = show a ++ show b ++ show c ++ show d
我必须定义a
,b
,c
和d
,以便:
GHCi> ip
"127.224.120.12"
成立。我怎么做?
答案 0 :(得分:10)
使用浮点数:
> let ip a b c d = show a ++ show b ++ show c ++ show d
> ip 127.2 24.12 0.1 2
"127.224.120.12"
答案 1 :(得分:5)
有不同的方法可以做到这一点。在任何情况下,默认的Show
实例可能都不适合您,这是问题的核心:您需要使用自定义Show
实例定义自己的类型。使用自定义实例(或隐藏实例)重新定义类型的常用方法是使用newtype
。
我们可以使用与Show
类似的String
实例,以便不会转义或添加"
:
newtype MyStr = MyStr String
instance Show MyStr where
show (MyStr s) = s
ip a b c d = show a ++ show b ++ show c ++ show d
a = MyStr "127."
b = MyStr "224."
c = MyStr "120."
d = MyStr "12"
main = print $ ip a b c d
另一种可能性是为Int
类型定义替代方案,其中使用.
时会附加show
。然后,我们将此类型用于ip
的前三个参数,并使用常规Int
作为最后一个参数(a
,b
,c
和{{ 1}}可以有不同的类型。)
d
请注意,在这两种情况下,解决方案都有点破解,但这是因为问题的本质。通常,您希望newtype MyInt = MyInt Int
instance Show MyInt where
show (MyInt s) = show s ++ "."
ip a b c d = show a ++ show b ++ show c ++ show d
a = MyInt 127
b = MyInt 224
c = MyInt 120
d = 12
main = print $ ip a b c d
的实例是技术性的,而不是"风格的"实际上:您希望显示有关值的所有信息,最好以可以使用Show
(通过定义相应的read
实例)回读的方式显示。对于样式输出,漂亮的打印机更合适。
答案 2 :(得分:1)
您的ip
功能会有所不同,具体取决于您要对a
,b
,c
和d
使用的内容:
如果您选择字符串:
ip1 :: String -> String -> String -> String -> String
ip1 a b c d = a ++ "." ++ b ++ "." ++ c ++ "." ++ d
如果你选择Ints:
ip2 :: Int -> Int -> Int -> Int -> String
ip2 a b c d = show a ++ "." ++ show b ++ "." ++ show c ++ "." ++ show d
<强>更新强>
也许这些为它们创建新类型和Show实例的示例 会有所帮助:
data Foo = F String
instance Show Foo where
show (F string) = "a string of length " ++ show (length string)
data Bar = B Double
instance Show Bar where
show (B adouble) = if adouble > 0 then "(positive)" else "(not positive)"
a = F "abc"
b = B 14.0
然后:
show a ++ show b
结果:
"a string of length 3(positive)"