2015-10-12 3 views
1

У меня есть функция ip, которую я не могу изменить:Работа с `show` в Haskell

ip = show a ++ show b ++ show C++ show d 

, и я должен определить a, b, c и d так, что:

GHCi> ip 
"127.224.120.12" 

. Как мне это сделать?

+0

Есть несколько способов сделать это. Какая у вас проблема? – dfeuer

+0

Концептуальные. Если я определяю, скажем, 'a =" 127 ",' show' добавляет все кавычки и escape-последовательности, а результат конкатенации неверен. Если я делаю 'a = 127.', Haskell рассматривает точку как функцию. И так далее. – Chiffa

+0

А какой другой тип вы могли бы использовать? –

ответ

4

Есть разные способы, которыми вы можете это сделать. В любом случае экземпляры по умолчанию 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 и 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 (путем определения соответствующего примера Read). Для вывода стилей более подходящий принтер.

+0

Я почти уверен, что это не то решение, которое ожидалось, но оно умно, и оно работает, поэтому спасибо. – Chiffa

+1

@Chiffa: Мне было бы интересно услышать о ожидаемом решении, если оно совсем другое. Я не могу думать иначе, чем использовать пользовательский экземпляр «Show». –

+0

Я обязательно отправлю его, как только получу. – Chiffa

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 

Обновление

Может быть, эти примеры создания новых типов и показать примеры их помогут:

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)" 
+0

У меня нет контроля над 'show', я могу предоставить только правильные аргументы. В противном случае ваши решения великолепны, и я уже думал об этом. – Chiffa

+0

Вы знаете, что такое типы a, b, c, d. Вы не можете определить 'ip', где иногда' a' является Int, а иногда и String. Покажите нам больше того, что вы пытаетесь сделать. – ErikR

+0

Я пытаюсь выбрать 'a',' b' и т. Д. Таким образом, что 'show' не добавляет к ним лишних символов. – Chiffa

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" 
+0

Ха-ха, хороший! – Yuuri

+0

Это именно тот ответ, который я имел в виду, когда я рекомендовал CodeGolf вместо этого сайта. К сожалению, другие видели это по-другому. – dfeuer

+0

Не могли бы вы пойти на codegolf, найти мой вопрос и скопировать ответ? Я бы сказал, что это именно так. – Chiffa

Смежные вопросы