访问本地linux机器

时间:2015-07-29 20:49:11

标签: haskell

我尝试使用此库访问IP:

http://jacob.stanley.io/2010/08/12/ip-addresses-and-mac-addresses-in-haskell/

src:

import Network.Info

    main = do
        ns <- getNetworkInterfaces
        mapM_ (putStr . showInterface) ns

    showInterface n = name n ++ "\n"
                   ++ "  IPv4: " ++ show (ipv4 n) ++ "\n"
                   ++ "  IPv6: " ++ show (ipv6 n) ++ "\n"
                   ++ "  MAC:  " ++ show (mac n) ++ "\n"

如何通过var?

中的ghci访问IPv4地址

类似的东西:

 let ipv4 = filterIpV4Address(ns)

ns的类型为ns :: [NetworkInterface],包含所有网络接口。我是Haskell的新手,并不理解这段代码。

变量&#34; n&#34;在行showInterface n = name n ++ "\n"

中设置

是否以某种方式设置在mapM_ (putStr . showInterface) ns行?

更新:

Prelude Network.Info Main> ns <- getNetworkInterfaces
Prelude Network.Info Main> ns

    [NetworkInterface {name = "Local Area Connection", ipv4 = 169.254.166.181, ipv6
    = fe80:0:0:0:94d4:87b2:7435:a6b5, mac = e8:11:32:d4:bf:04},NetworkInterface {nam
    e = "Wireless Network Connection", ipv4 = 192.168.1.12, ipv6 = fe80:0:0:0:b593:3
    47d:11d0:916f, mac = 00:1b:b1:28:a7:96},NetworkInterface {name = "Bluetooth Netw
    ork Connection", ipv4 = 169.254.131.172, ipv6 = fe80:0:0:0:6cc5:4071:a29b:83ac,
    mac = 90:a4:de:9c:a2:7a},NetworkInterface {name = "VirtualBox Host-Only Network"
    , ipv4 = 192.168.56.1, ipv6 = fe80:0:0:0:91e2:7d75:e6f7:d90f, mac = 0a:00:27:00:
    00:00},NetworkInterface {name = "Loopback Pseudo-Interface 1", ipv4 = 127.0.0.1,
     ipv6 = 0:0:0:0:0:0:0:1, mac = 00:00:00:00:00:00},NetworkInterface {name = "Loca
    l Area Connection* 12", ipv4 = 0.0.0.0, ipv6 = fe80:0:0:0:0:100:7f:fffe, mac = 0
    0:00:00:00:00:00},NetworkInterface {name = "isatap.home", ipv4 = 64.3.66.5, ipv6
     = fe80:0:0:0:0:5efe:c0a8:10c, mac = 00:00:00:00:00:00},NetworkInterface {name =
     "isatap.{7F25AE4D-EDF3-491F-ADED-642C194C94D9}", ipv4 = 0.0.0.0, ipv6 = fe80:0:
    0:0:0:5efe:c0a8:3801, mac = 00:00:00:00:00:00}]

那么如何提取价值:192.168.1.12?

1 个答案:

答案 0 :(得分:3)

从文档中可以得到NetworkInterface

的定义
data NetworkInterface = NetworkInterface { name :: String
                                         , ipv4 :: IPv4
                                         , ipv6 :: IPv6
                                         , mac :: MAC}

这告诉您,如果您想访问name等,您具有相同名称的访问者功能,类型签名为name :: NetworkInterface -> String(类似于其他人) - 因此,如果您想要提取您正在寻找类似?? :: (NetworkInterfaces -> String) -> [NetworkInterfaces] -> [String]的网络接口列表中的名称,这是此类型签名?? :: (a -> b) -> [a] -> [b]的特殊情况,将其放入hoogle,您会看到一个名为{{1}的函数作为第一个结果。

因此,为了收集网络名称,您只需要map

但是如果你想将这些函数应用于map names ns的结果,那么这个getNetworkInterfaces指标就不适合这种类型的签名;但是存在一个名为IO的函数 - 我们已经看到的函数fmap的更一般版本可以帮助我们。

map采用一个容器(在这种情况下是fmap和一个对容器起作用的函数,并以合理的方式将该函数应用于所述容器,(顺便说一句,提供这种功能的所有容器都是叫IO)。

因此,为了直接从Functors获取你的名字,你需要输入你的ghci:

getNetworkInterfaces

或使用'backtick-syntax'

Prelude> ns <- fmap (map name) getNetworkInterfaces

如果你Prelude> ns <- map name `fmap` getNetworkInterfaces ,你会得到这个非常方便的中缀运算符import Control.Applicative,可让你将其编写为<$>

修改

map name <$> getNetworkInterfaces实际上是一个函数 - 它的类型签名被省略 - 是showInterface,这意味着它需要showInterface :: NetworkInterface -> String并生成NetworkInterface。所以String实际上是一个网络接口,它(通过我发布的数据声明)有4个访问函数,用于获取nnameipv4和{{1} }。不幸的是,产生ipv6输出的mac函数具有类型签名putStr,它只适用于已经stdout的{​​{1}},以获得剩余的3为了工作,我们必须使用haskell的String -> IO () - 方法,称为nameString所做的其余工作是将toString()show运算符拼接在一起。 (旁注:showInterface将两个相同类型的列表拼接在一起,而String只是++ = (++)列表

那么String最后会做什么 - 它与[Char]非常类似(因此名称),但它允许发生副作用,幸运的是足够打印到stdout({{1} }})是这样的副作用。请注意,有两个函数非常相似CharmapM_您可能会不时在haskell-land中看到的下划线表示丢弃/不需要的东西,在这种情况下是结果 - 其中这种情况map会生成putStrmapM只会忘记列表并生成mapM_(说IO单位 - 您可以在C-中考虑mapM就像语言一样,我的助记符是IO [()],其中包含io,但有一些东西可以隐藏它并拼写错误的顺序。)

顺便提一下,mapM_的类型签名也被省略IO (),它与void完全吻合。